javascript-Angularjs监视父范围的更改

我正在写指令,并且需要注意父作用域的更改。 不知道我是否正在按照首选方式执行此操作,但是它不能与以下代码一起使用:

  scope.$watch(scope.$parent.data.overlaytype,function() {
    console.log("Change Detected...");
  })

它记录了窗口加载,但是即使更改了overlaytype,也不会再次登录。

如何查看overlaytype的变化?

编辑:这是整个指令。 不确定我为什么要使用儿童镜

/* Center overlays vertically directive */
aw.directive('center',function($window){
  return {
    restrict : "A",
    link : function(scope,elem,attrs){

      var resize = function() {
        var winHeight = $window.innerHeight - 90,
            overlayHeight = elem[0].offsetHeight,
            diff = (winHeight - overlayHeight) / 2;
            elem.css('top',diff+"px");
      };

      var watchForChange = function() {
        return scope.$parent.data.overlaytype;
      }
      scope.$watch(watchForChange,function() {
        $window.setTimeout(function() {
          resize();
        }, 1);
      })

      angular.element($window).bind('resize',function(e){
        console.log(scope.$parent.data.overlaytype)
        resize();
      });
    }
  };
});
wesbos asked 2020-07-29T22:09:51Z
5个解决方案
73 votes

如果要监视父范围的属性,则可以使用父范围中的$watch方法。

//intead of $scope.$watch(...)
$scope.$parent.$watch('property', function(value){/* ... */});

编辑2016:上面的应该可以正常工作,但这并不是一个干净的设计。 尝试改用指令或组件,然后将其依赖项声明为绑定。 这将导致更好的性能和更清洁的设计。

Petr Peller answered 2020-07-29T22:12:43Z
22 votes

我建议您使用控制器之间的$ broadcast执行此操作,这似乎是父/子控制器之间进行通信的角度方式

这个概念很简单,您可以在父控制器中观察值,然后在发生修改时将其广播并在子控制器中捕获它

这是展示它的小提琴:[http://jsfiddle.net/DotDotDot/f733J/]

父控制器中的部分如下所示:

$scope.$watch('overlaytype', function(newVal, oldVal){
    if(newVal!=oldVal)
        $scope.$broadcast('overlaychange',{"val":newVal})
});

并在子控制器中:

$scope.$on('overlaychange', function(event, args){
    console.log("change detected")
    //any other action can be perfomed here
});

使用此解决方案的好处是,如果您想在另一个子控制器中观看修改,则可以捕获相同的事件

玩得开心

编辑:我没有看到您上一次编辑,但是我的解决方案也适用于该指令,我更新了上一个小提琴([http://jsfiddle.net/DotDotDot/f733J/1/])

我修改了您的指令,以强制其创建子范围并创建控制器:

directive('center',function($window){
  return {
    restrict : "A",
    scope:true,
    controller:function($scope){
        $scope.overlayChanged={"isChanged":"No","value":""};
        $scope.$on('overlaychange', function(event, args){
        console.log("change detected")
        //whatever you need to do

    });
  },
link : function(scope,elem,attrs){

  var resize = function() {
    var winHeight = $window.innerHeight - 90,
        overlayHeight = elem[0].offsetHeight,
        diff = (winHeight - overlayHeight) / 2;
        elem.css('top',diff+"px");
  };
  angular.element($window).bind('resize',function(e){
    console.log(scope.$parent.data.overlaytype)
    resize();
      });
    }
  };
});
DotDotDot answered 2020-07-29T22:13:39Z
7 votes

您应该在子作用域上具有data属性,作用域在父作用域和子作用域之间使用原型继承。

同样,$ watch方法期望的第一个参数是要计算的表达式或函数,而不是变量的值。因此,您应该发送它。

Naor Biton answered 2020-07-29T22:12:19Z
6 votes

如果您要查看子作用域内的父作用域变量,则可以在$watch上添加true作为第二个参数。每次修改对象时都会触发手表

$scope.$watch("searchContext", function (ctx) {
                ...
            }, true);
S. Ktifa answered 2020-07-29T22:13:59Z
2 votes

好了,我花了两分钱,我也很喜欢事件选项:

更新的小提琴[http://jsfiddle.net/enU5S/1/]

HTML

<div ng-app="myApp" ng-controller="MyCtrl">
    <input type="text" model="model.someProperty"/>
    <div awesome-sauce some-data="model.someProperty"></div>
</div>

JS

angular.module("myApp", []).directive('awesomeSauce',function($window){
  return {
    restrict : "A",
      template: "<div>Ch-ch-ch-changes: {{count}} {{someData}}</div>",
      scope: {someData:"="},
      link : function(scope,elem,attrs){
        scope.count=0;
        scope.$watch("someData",function() {
            scope.count++;
        })
    }
  };
}).controller("MyCtrl", function($scope){
    $scope.model = {someProperty: "something here");
});

我在这里显示的是您可以有一个变量,该变量具有与子项和父项之间的两种方式绑定,但不需要子级达到其父项即可获得属性。 如果您在指令上方添加新的父代,那么达到目标的趋势就会变得疯狂。

如果在框中键入内容,它将更新控制器上的模型,这又绑定到指令上的属性,因此它将在指令中更新。 在指令链接功能中,它具有监视设置,因此,只要范围变量发生变化,它都会增加一个计数器。

在此处查看有关隔离范围以及使用= @或&之间的区别的更多信息:[http://www.egghead.io/]

shaunhusain answered 2020-07-29T22:14:45Z
translate from https://stackoverflow.com:/questions/17838745/angularjs-watch-for-change-in-parent-scope