Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript $监视对象_Javascript_Angularjs_Angularjs Scope - Fatal编程技术网

Javascript $监视对象

Javascript $监视对象,javascript,angularjs,angularjs-scope,Javascript,Angularjs,Angularjs Scope,我想查看字典中的更改,但由于某些原因,不调用watch callback 以下是我使用的控制器: function MyController($scope) { $scope.form = { name: 'my name', surname: 'surname' } $scope.$watch('form', function(newVal, oldVal){ console.log('changed'); })

我想查看字典中的更改,但由于某些原因,不调用watch callback

以下是我使用的控制器:

function MyController($scope) {
    $scope.form = {
        name: 'my name',
        surname: 'surname'
    }

    $scope.$watch('form', function(newVal, oldVal){
        console.log('changed');
    });
}
这是

我预计每次更改姓名时都会触发$watch回调,但事实并非如此


正确的方法是什么?

调用
$watch
,第三个参数为
true

$scope.$watch('form', function(newVal, oldVal){
    console.log('changed');
}, true);
默认情况下,在比较JavaScript中的两个复杂对象时,将检查它们是否“引用”相等,这会询问两个对象是否引用相同的对象,而不是“值”相等,这会检查这些对象的所有属性的值是否相等

根据,第三个参数用于
objectEquality

objectEquality==true
时,根据函数确定watchExpression的不等式。要保存对象的值以供以后比较,请使用函数。因此,这意味着观看复杂对象会对记忆和性能产生不利影响


表单
对象没有更改,只更改了
名称
属性

更新

试试这个:

function MyController($scope) {
    $scope.form = {
        name: 'my name',
        surname: 'surname'
    }

    function track(newValue, oldValue, scope) {
        console.log('changed');
    };

    $scope.$watch('form.name', track);
}

代码不工作的原因是默认情况下,
$watch
执行引用检查。因此,简而言之,它确保传递给它的对象是新对象。但在您的例子中,您只是修改表单对象的一些属性,而不是创建一个新属性。为了使其工作,您可以将
true
作为第三个参数传递

$scope.$watch('form', function(newVal, oldVal){
    console.log('invoked');
}, true);
它可以工作,但您可以使用$watchCollection,它将比$watch更有效,因为
$watchCollection
将监视表单对象上的浅层属性。例如

$scope.$watchCollection('form', function (newVal, oldVal) {
    console.log(newVal, oldVal);
});

在查找表单对象更改时,最好的观察方法是使用
$watchCollection
。请查看官方的不同性能特征

您必须兑换$watch

函数MyController($scope){
$scope.form={
姓名:'我的名字',
}
$scope.$watch('form.name',函数(newVal,oldVal){
console.log('changed');
});
}

姓名:
{{form}}

Little性能提示如果某人有一种数据存储类型的服务,并且具有键对->值对:

如果您有一个名为数据存储的服务,则可以在大数据对象发生变化时更新时间戳。 通过这种方式,您不需要深入观察整个对象,而只需要观察更改的时间戳

app.directive("myDir", function ($scope, dataStore) {
    $scope.dataStore = dataStore;
    $scope.$watch('dataStore.getChange("myKey")', function(newVal, oldVal){
        if(newVal !== oldVal && newVal){
            // Data changed
        }
    });
});
在指令中,您只需观察要更改的时间戳

function MyController($scope) {

    $scope.array = [
        data1: {
            name: 'name',
            surname: 'surname'
        },
        data2: {
            name: 'name',
            surname: 'surname'
        },
    ]


    $scope.$watch(function() {
        return $scope.data,
    function(newVal, oldVal){
        console.log(newVal, oldVal);
    }, true);

对于任何想要监视对象数组中对象的更改的人来说,这似乎对我很有效(本页上的其他解决方案没有):


这是一个很好的答案,但我想有时候你不想递归地观察对象。默认情况下,如果未传递
true
,则如果监视的值是对象或数组,它将检查引用是否相等。在这种情况下,您应该明确指定属性,如
$scope.$watch('form.name')
$scope.$watch('form.name')
谢谢。这正是我错过的。Jason,你说得对-你并不总是想看到递归对象,但在我的情况下,这正是我所需要的。ImmutableJS和引用比较可能有助于提高性能。回答一个两年前的问题时,答案可能与现有问题几乎完全相同?不酷。我认为值得一提的是,在这种情况下,您将失去访问存储数据旧值的功能
newVal
oldVal
在本例中是时间戳值,而不是观察到的对象值。这并不是说这个答案无效,我只是认为这是一个值得一提的缺点。没错,当我想加载一个复杂的数据结构作为某个数据的源(例如某个数据的新版本)时,我通常使用这种方法。如果我关心新的和旧的值,我不会将它们存储在大型复杂对象中,相反,我会用一个小文本表示我关心的东西,并观察它的变化,或者在时间戳变化时获取它。
app.directive("myDir", function ($scope, dataStore) {
    $scope.dataStore = dataStore;
    $scope.$watch('dataStore.getChange("myKey")', function(newVal, oldVal){
        if(newVal !== oldVal && newVal){
            // Data changed
        }
    });
});
function MyController($scope) {

    $scope.array = [
        data1: {
            name: 'name',
            surname: 'surname'
        },
        data2: {
            name: 'name',
            surname: 'surname'
        },
    ]


    $scope.$watch(function() {
        return $scope.data,
    function(newVal, oldVal){
        console.log(newVal, oldVal);
    }, true);