একটি কৌণিক নির্দেশে ডেটা পরিবর্তনের জন্য $ নজর রাখা


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সেটটিতে intoোকানো হয়েছে । আমি প্রস্তুত একটি টেবিল প্রতিবার "অ্যাড" বোতামটি চাপলে আপডেট হয়।

<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জন্য যে নির্দেশিকাটি সেট আপ করেছিলাম তা যখন ঘটে থাকে তখন তা বরখাস্ত করা হয় না।

আমি এইচটিএমএলে আমার ট্যাগটি সংজ্ঞায়িত করেছি:

<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
একটি নতুন টিপ যদি নিউভ্যালুতে কখনও 0, মিথ্যা, "" বা এর মতো অন্য কোনও কিছুর সমান হয় তবে আপনার "আমি একটি ডেটা পরিবর্তন দেখছি!" আগুন লাগবে না উদাহরণস্বরূপ, মূল মানটি সত্য ছিল, নতুন মূল্যটি মিথ্যা। সেখানে কেবলমাত্র নতুন ভ্যালু ব্যবহার করার জন্য এটি পর্যাপ্ত হওয়া উচিত, যদি কিছু পরিবর্তন হয় তবে কেবল সেই ঘড়িটিকেই ডাকা হয়। যদি এটি কোনও বস্তু হয় তবে তা তাত্ক্ষণিকভাবে বলা হবে।
ম্যাথিউ বার্গ

ভাল টিপ, ধন্যবাদ! আমি 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 প্রবর্তিত $ ঘড়ি সংগ্রহ

অগভীর কোনও বস্তুর বৈশিষ্ট্য দেখায় এবং আগুন জ্বলতে থাকে যখনই কোনও বৈশিষ্ট্য পরিবর্তিত হয় (অ্যারেগুলির জন্য, এটি বোঝায় অ্যারে আইটেমগুলি পর্যবেক্ষণ করা; বস্তুর মানচিত্রের জন্য, এটি বৈশিষ্ট্যগুলি দেখানো বোঝায়)

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

1
দুর্দান্ত কাজ করছে। ধন্যবাদ!
খারাপ ক্লোসট বানর

1
সাহায্য করে আনন্দ পেলাম. Watch ওয়াচ ফাংশনটির সাথে পরীক্ষা চালিয়ে যান যেহেতু এটি দেখতে পাবে তার মত প্রকাশগুলি বেশ বৈচিত্রপূর্ণ।
Liviu টি।

1
কীভাবে কেবল গভীর অ্যারেগুলি পরীক্ষা করা যায় তা লক্ষ করার জন্য ধন্যবাদ;)
ভেরিটাস

এটা দুঃখের বিষয় আমি একাধিকবার উত্থাপন করতে পারি না .. আমি আপনাকে একটি অনুগ্রহ দান করব, যে 2 ঘন্টা আমি তার সন্ধানে হারিয়েছি for
অ্যালেক্স আরভানিতিডিস

ভাল উত্তর সেখানে।
chovy

2

কারণ আপনি যদি আপনার ডেটার গভীরতার সাথে এটি ট্রিগার করতে চান তবে আপনাকে trueআপনার শ্রোতার 3 তম যুক্তিটি পাস করতে হবে default এটি ডিফল্ট হিসাবে falseএবং এটি আপনার কাজটি কেবল ট্রিগার করবে তা কেবল তখনই আপনার ভেরিয়েবলটি ক্ষেত্র পরিবর্তন করবে না


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));
                }
            });
        }
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.