【问题标题】:AngularJS: triggering a controller function when a variable changes into a directiveAngularJS:当变量变为指令时触发控制器功能
【发布时间】:2015-07-20 10:28:42
【问题描述】:

我有一个指令来做两件事:(i) 它管理 HTML 中某些选项卡的可视化,(ii) 它 $watches 对象 myObj 在会话中的值存储并将此对象保存在名为myData 的变量中。代码如下:

.directive('panelManager', function(){
    return {
        restrict: 'E',
        templateUrl: 'foo.html',

        controller: ['$scope', '$window',  function($scope, $window) {
            pn = this;
            pn.tab = 1; // init

            this.selectTab = function(setTab) {
                pn.tab = setTab;
            };

            this.isSelected = function(checkTab) {
                return pn.tab === checkTab;
            };

            $scope.$watch(function () {
                return $window.sessionStorage.getItem('myObj');
            }, function (value) {
                pn.myData = JSON.parse(value);
            });
        }],
        controllerAs: 'panels'
    };
})

我有一个控制器来调用一个 WS 传递上述myData 的属性foo,每次它发生变化时。这里是:

.controller('MyDataController', ['$http', function($http) {

    pdc = this;
    pdc.myResultset = [];

    pdc.getDetails = function(val) {
        return $http.get("myUrl"+val+"/").then(function(response){
              pdc.myResultset= response.data;
        });
    };
}]);

有没有办法在该控制器中触发 getDetails 并在每次 myData 更改值时将 val = MyData.foo 传递给它? 这样,我就可以在myResultset中存储WS的当前结果集并将其分配给本地范围。

【问题讨论】:

  • 一种选择是将 myData 放在根范围内,然后:1. 您仍然可以从指令访问它 2. 您可以在 MyDataController 中查看更改

标签: javascript angularjs


【解决方案1】:

您可以从指令中发出,但您需要关联控制器中的$rootScope。所以声明变成:

controller: ['$rootScope', '$scope', '$window',  function($rootScope, $scope, $window) {

然后,你可以这样做:

$scope.$watch(function () {
    return $window.sessionStorage.getItem('myObj');
}, function (value) {
    pn.myData = JSON.parse(value);
    $rootScope.$broadcast('valueChanged', pn.myData);
});

在你的控制器中:

.controller('MyDataController', ['$http', '$scope', function($http, $scope) {

    pdc = this;
    pdc.myResultset = [];

    pdc.getDetails = function(val) {
        return $http.get("myUrl"+val+"/").then(function(response){
            pdc.myResultset= response.data;
        });
    };

    $scope.$on('valueChanged', function(event, data) {
        pdc.getDetails(data.foo); //pass data.foo to the function
    });
}]);

【讨论】:

  • 完美,非常酷! PS:如果我必须在更多控制器中重复使用这个策略,我可以在工厂中插入$scope.on(...);吗? PPS:在broadcaston 之前缺少$
  • 感谢您的反馈 :) 当然可以!看看下面的链接:stackoverflow.com/a/16492065/4693496.
  • 不客气! :) 对读者来说另一件有趣的事情:在第一次加载时,myData 为空,不应该发生valueChanged,但由于某种原因,pdc.getDetails(...) 内的$scope.on(...); 会在控制台中触发此错误:Cannot read property ' foo' of null
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多