एक कोणीय निर्देश में डेटा परिवर्तनों के लिए $ watch'ing


132

$watchअंदर डेटा में हेरफेर करते समय (जैसे डेटा सम्मिलित करना या निकालना) मैं एक कोणीय निर्देश में एक चर को कैसे ट्रिगर कर सकता हूं , लेकिन उस चर के लिए एक नई वस्तु असाइन नहीं करता है?

मेरे पास एक साधारण डेटासेट है जिसे वर्तमान में JSON फ़ाइल से लोड किया जा रहा है। मेरा कोणीय नियंत्रक ऐसा करता है, साथ ही कुछ कार्यों को परिभाषित करता है:

App.controller('AppCtrl', function AppCtrl($scope, JsonService) {
    // load the initial data model
    if (!$scope.data) {
        JsonService.getData(function(data) {
            $scope.data = data;
            $scope.records = data.children.length;
        });
    } else {
        console.log("I have data already... " + $scope.data);
    }

    // adds a resource to the 'data' object
    $scope.add = function() {
        $scope.data.children.push({ "name": "!Insert This!" });
    };

    // removes the resource from the 'data' object
    $scope.remove = function(resource) {
        console.log("I'm going to remove this!");
        console.log(resource);
    };

    $scope.highlight = function() {

    };
});

मेरे पास फ़ंक्शन <button>ठीक से कहा जाता है $scope.add, और $scope.dataसेट में नई ऑब्जेक्ट ठीक से डाली गई है । मेरे द्वारा सेट की गई तालिका में "ऐड" बटन को हिट करने पर हर बार अपडेट होता है।

<table class="table table-striped table-condensed">
  <tbody>
    <tr ng-repeat="child in data.children | filter:search | orderBy:'name'">
      <td><input type="checkbox"></td>
      <td>{{child.name}}</td>
      <td><button class="btn btn-small" ng-click="remove(child)" ng-mouseover="highlight()"><i class="icon-remove-sign"></i> remove</button></td>
    </tr>
  </tbody>
</table>

हालाँकि, यह देखने के लिए मैंने जो निर्देश सेट किया $scope.dataहै, यह सब होने पर निकाल नहीं दिया जा रहा है।

मैं HTML में अपना टैग परिभाषित करता हूं:

<d3-visualization val="data"></d3-visualization>

जो निम्नलिखित निर्देश के साथ जुड़ा हुआ है (प्रश्न विवेक के लिए छंटनी):

App.directive('d3Visualization', function() {
    return {
        restrict: 'E',
        scope: {
            val: '='
        },
        link: function(scope, element, attrs) {
            scope.$watch('val', function(newValue, oldValue) {
                if (newValue)
                    console.log("I see a data change!");
            });
        }
    }
});

मुझे "I see a data change!"शुरुआत में ही संदेश मिल जाता है , लेकिन उसके बाद भी मैंने "ऐड" बटन नहीं मारा।

$watchजब मैं ऑब्जेक्ट से ऑब्जेक्ट्स को जोड़ / हटा रहा / रही हूं data, तो ऑब्जेक्ट को असाइन करने के लिए एक नया डेटासेट नहीं मिलने से मैं घटना को कैसे ट्रिगर कर सकता हूं data?


5
बस एक त्वरित टिप अगर newValue कभी 0, झूठे, "" या कुछ और के समान होता है जैसे कि आपका "मुझे डेटा परिवर्तन दिखाई देता है!" आग नहीं होगी। उदाहरण के लिए, मूल मूल्य सही था, नया वैल्यू झूठा है। यह पर्याप्त होना चाहिए बस वहाँ में newValue का उपयोग करें, कि घड़ी केवल कहा जाता है अगर कुछ बदल गया है। यदि यह एक वस्तु है, तो इसे तुरंत कहा जाएगा।
मैथ्यू बर्ग

अच्छा टिप, धन्यवाद! मैं ifबयान को बंद कर दूंगा ।
ईविल कोठरी बंदर

जवाबों:


218

आपको गहरी ऑब्जेक्ट गंदी जाँच सक्षम करने की आवश्यकता है। डिफ़ॉल्ट रूप से कोणीय केवल आपके द्वारा देखे जाने वाले शीर्ष स्तर चर के संदर्भ की जांच करता है।

App.directive('d3Visualization', function() {
    return {
        restrict: 'E',
        scope: {
            val: '='
        },
        link: function(scope, element, attrs) {
            scope.$watch('val', function(newValue, oldValue) {
                if (newValue)
                    console.log("I see a data change!");
            }, true);
        }
    }
});

स्कोप देखें । $ घड़ी फ़ंक्शन का तीसरा पैरामीटर गहरी गंदी जाँच को सक्षम करता है यदि यह सच है।

ध्यान दें कि गहरी गंदी जाँच महंगी है । इसलिए अगर आपको पूरे dataचर के बजाय बच्चों की सरणी देखने की जरूरत है तो सीधे चर को देखें।

scope.$watch('val.children', function(newValue, oldValue) {}, true);

संस्करण 1.2.x ने $ watchCollection पेश किया

उथला एक वस्तु के गुणों को देखता है और जब भी कोई गुण बदलता है (सरणियों के लिए, इसका तात्पर्य सरणी वस्तुओं को देखने से है; वस्तु मानचित्रों के लिए, इसका अर्थ है गुणों को देखना;

scope.$watchCollection('val.children', function(newValue, oldValue) {});

1
बढ़िया काम कर रहा है। धन्यवाद!
ईविल कोठरी बंदर

1
मदद करने में खुशी। $ घड़ी फ़ंक्शन के साथ प्रयोग करना जारी रखें क्योंकि यह देख सकने वाले भाव काफी विविध हैं।
लिवियू टी।

1
यह देखने के लिए धन्यवाद कि केवल गहरी सरणियों की जांच कैसे की जाती है;)
वेरिटास

यह अफ़सोस की बात है कि मैं एक से अधिक बार उत्थान नहीं कर सकता हूँ .. मैं आपको एक इनाम दूंगा, 2h के लिए मैं उस की तलाश में खो गया।
एलेक्स अरवनितिडिस

वहाँ सबसे अच्छा जवाब।
चॉबी

2

क्योंकि अगर आप अपने डेटा को डीप के साथ ट्रिगर करना चाहते हैं, तो आपको trueअपने श्रोता के 3 वें तर्क को पास करना होगा। लेकिन यह डिफ़ॉल्ट है falseऔर यह meens करता है कि आप कार्य करेंगे तभी ट्रिगर होगा, जब आपका वैरिएबल नहीं बदलेगा


1

एक निर्देश के लिए मेरा संस्करण जो उपलब्ध होने के बाद डेटा को प्लॉट करने के लिए jqplot का उपयोग करता है:

    app.directive('lineChart', function() {
        $.jqplot.config.enablePlugins = true;

        return function(scope, element, attrs) {
            scope.$watch(attrs.lineChart, function(newValue, oldValue) {
                if (newValue) {
                    // alert(scope.$eval(attrs.lineChart));
                    var plot = $.jqplot(element[0].id, scope.$eval(attrs.lineChart), scope.$eval(attrs.options));
                }
            });
        }
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.