$ watch如何通过组件的控制器更改服务中的变量?

时间:2019-08-22 13:31:03

标签: angularjs

我遍历了SO的所有相关主题,即以下两个主题:

$watch not detecting changes in service variable

$watch not detecting changes in service variable

正在解决相同的问题,但我无法使其正常运行。与上述情况不同,我使用的是组件的控制器,因此这可能与缺少组件idk的绑定有关。希望能得到一些帮助。

获得服务

(function (angular) {
    'use strict';

    angular
        .module('Test')
        .service('ShareData', ShareData);

    ShareData.$inject = [];

    function ShareData() {
        let vm = this;

        vm.indexes = [];

        vm.setIndexes = function(firstIndexParam, lastIndexParam, message) {
            if (leaderIndexParam !== undefined || partnerIndexParam !== undefined) {
                vm.indexes.mainIndex = firstIndexParam;
                vm.indexes.secondaryIndex = lastIndexParam;
                vm.indexes.message = message;
            }
        };

        vm.getIndexes = function() {
            return vm.indexes;
        };
    }
})(angular);

它在3个组件中使用。其中两个将数据发送到服务中,第三个使用此数据。数据发送是通过以下方式完成的:

ShareData.setIndexes(firstIndex, secondIndex, 'update_indexes');

现在这是我的问题。在主父控制器中,我可以通过

轻松地访问数据
ShareData.getIndexes();

但是我的问题是我需要更改索引才能触发父控制器中的某些操作,所以我按照SO此处相关问题的规定尝试这样做:

$scope.$watch('ShareData.getIndexes()', function(newVal) {
   console.log('New indexes arrived', newVal);
});

在主控制器中,我正在注入服务:

TabController.$inject = ['ShareData'];

并像这样使用它:

let indexService = ShareData.getIndexes();

正如我所说,当我显式调用该函数时,就可以获取数据。问题在于它需要由服务本身触发。

无论作出什么萨满教仪式,它都不起作用:)现在,很明显,我缺少了一些东西。我应该以某种方式将此服务绑定到组件吗?如果可以,如何完成?还是解决方案完全不起作用,在我的情况下无法实现?一个建议表示赞赏!

更新:我已经有了一个与$rootScope.$broadcast一起使用同一服务的功能性解决方案,但是我的目标是摆脱它,而不使用$ rootScope。

1 个答案:

答案 0 :(得分:2)

问题在于,您实际上从未更改过df.loc[df.index.get_level_values(1).isin(positions), 'col1'] = True 的值-它始终指向同一数组。 vm.indexes仅修改此数组的属性。这就是setIndexes(默认情况下仅检查引用是否相等)无法发现更改的原因。

(至少)有两种方法可以解决此问题:或者通过在其中添加第三个参数,使$watch检查对象的相等性:

$watch

...或(我认为更好)重写$scope.$watch('ShareData.getIndexes()', function(newVal) { console.log('New indexes arrived', newVal); }, true); 函数,以便它会在发生更改时创建set的新实例:

indexes

作为附带说明,仅调用vm.setIndexes = function(firstIndexParam, lastIndexParam, message) { if (leaderIndexParam === undefined && partnerIndexParam === undefined) { return; } vm.indexes = vm.indexes.slice(); Object.assign(vm.indexes, { mainIndex: firstIndexParam, secondaryIndex: lastIndexParam, message: message }); }; 不会触发摘要-并且setIndexes()侦听器仅在触发摘要时检查其表达。