Angularjs注意父范围的变化

wes*_*bos 43 javascript scope angularjs

我正在编写一个指令,我需要查看更改的父作用域.不确定我是否这样做是首选方式,但它不能使用以下代码:

  scope.$watch(scope.$parent.data.overlaytype,function() {
    console.log("Change Detected...");
  })
Run Code Online (Sandbox Code Playgroud)

它记录了窗口加载,但即使更改了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();
      });
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

Pet*_*ler 73

如果要查看父作用域的属性,可以使用$watch父作用域中的方法.

//intead of $scope.$watch(...)
$scope.$parent.$watch('property', function(value){/* ... */});
Run Code Online (Sandbox Code Playgroud)

编辑2016: 上面应该工作得很好,但它不是一个真正的干净设计.尝试使用指令组件,并将其依赖项声明为绑定.这应该会带来更好的性能和更清洁的设计.


Dot*_*Dot 22

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

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

这是一个演示它的小提琴:http://jsfiddle.net/DotDotDot/f733J/

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

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

并在子控制器中:

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

这个解决方案很好,如果你想在另一个子控制器中观察修改,你可以抓住同一个事件

玩得开心

编辑:我没有看到你最后编辑,但我的解决方案也适用于指令,我更新了以前的小提琴(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();
      });
    }
  };
});
Run Code Online (Sandbox Code Playgroud)


Nao*_*ton 7

您应该在子范围上具有data属性,范围使用父范围和子范围之间的原型继承.

另外,$ watch方法所期望的第一个参数是要计算的表达式或函数,而不是变量的值.所以你应该发送它.


小智 6

如果您正在寻找在子范围内观看父范围变量,您可以true在您的范围内添加第二个参数$watch.这将在每次修改对象时触发您的手表

$scope.$watch("searchContext", function (ctx) {
                ...
            }, true);
Run Code Online (Sandbox Code Playgroud)