Angular:控制器和指令之间的共享数据。 $ watch如何运作

时间:2016-11-16 16:37:04

标签: javascript angularjs watch

我在JS方面有一些技巧,而且我几乎是新的Angular。我有一个关于$ watch如何在我的情况下工作的问题。任务 - 以适当的方式在指令和控制器之间共享数据。据我了解,最佳做法是使用服务共享数据。所以我有:

指令

angular.module('app.directives').directive('ffDomains', function(sharedData) {
...
    $scope.navigateTo = function(domain, event) {
        $scope.activeDomain = domain;
        sharedData.setDomain(domain);
    };
...
}

工厂

angular.module("app.factories").factory('sharedData', function () {
    var domain = null;

    return {
        setDomain: setDomain,
        getDomain: getDomain
    };

    function setDomain(_domain) {
        domain = _domain;
    }

    function getDomain() {
        return domain;
    }

});

和控制器

angular.module('app.controllers').controller('mainController', ['$scope', 'sharedData', function ($scope, sharedData) {

    $scope.currentDomain = {};
    $scope.$watch(function() {return sharedData.getDomain()}, function() {

        if (sharedData.getDomain()) {
            $scope.currentDomain = sharedData.getDomain();
        } else {
            $scope.currentDomain.domain = 'All domains';
        }
    });

}]);

问题是为什么我应该在监视中使用 function(){return sharedData.getDomain()} 而不是 sharedData.getDomain()?最后一个是我服务中变量的链接。为什么还不够呢?

请感谢您的帮助。我很感激你的时间。

2 个答案:

答案 0 :(得分:0)

在这种特定情况下,您指的是工厂,因此是当前范围之外的变量。

当你将一个变量传递给观察者时,angular将评估当前范围内的字符串,显然它不存在。

var domain sharedData.getDomain();
$scope.$watch('domain', function(newVal, oldVal) { 
//domain doesn't exist in the current scope

});

每当你想要观察当前范围之外的东西时,你必须提供一个回调作为在dygest循环期间触发的参数。

$scope.$watch(function(){
  return sharedData.getDomain()
}, function(newVal, oldVal) { 

});

答案 1 :(得分:0)

关于你的问题:

  

问题是为什么我应该使用function(){return   sharedData.getDomain()}而不是手表中的sharedData.getDomain()?   最后一个是我服务中的域变量的链接。为什么不呢   对它充满了什么呢?

official documentation

中所述
  

每次调用$ digest()时都会调用watchExpression   返回将要观看的值。 (watchExpression不应该   使用相同的输入多次执行时更改其值   因为它可能会被$ digest()多次执行。那是,   watchExpression应该是幂等的。)

watchExpression可以是:

  • 一个字符串
  • 一个功能

"字符串"是有效的AngulaJS expression。如文档中所述:

  

Angular表达式就像JavaScript表达式,具有以下内容   差异:

     
      
  • 上下文:根据全局窗口评估JavaScript表达式。在Angular中,表达式是针对scope对象进行评估的。
  •   
     

...

所以,如果你指定一个"字符串"在watchExpression中,AngularJS将根据范围评估表达式。

如果您将function作为watchExpression传递,则该函数将返回要监视的值。 "功能"每次在范围内无法轻松检索要观看的值时使用(否则您可以使用"字符串"表达式而不是"函数"一个)。

在您的示例中,watchExpression为:

function() {return sharedData.getDomain()}

sharedData服务不是范围中定义的变量(例如$scope.sharedData = {...}),而是在其他地方定义的Angular服务。因此,您必须使用函数()作为watchExpression,否则Angular无法监视域中的更改。