Javascript Angularjs监视父范围中的更改

Javascript Angularjs监视父范围中的更改,javascript,angularjs,scope,Javascript,Angularjs,Scope,我正在写一个指令,我需要观察父范围的变化。不确定是否以首选方式执行此操作,但它不适用于以下代码: scope.$watch(scope.$parent.data.overlaytype,function() { console.log("Change Detected..."); }) 它会记录在窗口加载上,但不会再次记录,即使覆盖类型已更改 如何查看overlytype以获得更改 编辑:这是整个指令。不太清楚我为什么要用儿童窥镜 /* Center overlays vert

我正在写一个指令,我需要观察父范围的变化。不确定是否以首选方式执行此操作,但它不适用于以下代码:

  scope.$watch(scope.$parent.data.overlaytype,function() {
    console.log("Change Detected...");
  })
它会记录在窗口加载上,但不会再次记录,即使覆盖类型已更改

如何查看
overlytype
以获得更改

编辑:这是整个指令。不太清楚我为什么要用儿童窥镜

/* 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();
      });
    }
  };
});
您应该在子作用域上具有data属性,作用域在父作用域和子作用域之间使用原型继承


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

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

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

这里有一把小提琴演示:

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

$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
});
这个解决方案的优点是,如果您想在另一个子控制器中观看修改,您可以捕获相同的事件

玩得开心

编辑:我没有看到您上次编辑,但我的解决方案也适用于该指令,我更新了以前的fiddle()

我修改了您的指令,强制它创建子作用域并创建控制器:

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();
      });
    }
  };
});

好吧,这花了我一段时间,这是我的两分钱,不过我也很喜欢活动选项:

更新的小提琴

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");
});
angular.module(“myApp”,[])指令('awesomeSauce',函数($window){
返回{
限制:“A”,
模板:“Ch更改:{{count}}{{someData}}”,
作用域:{someData:'=“},
链接:功能(范围、要素、属性){
scope.count=0;
作用域.$watch(“someData”,function()){
scope.count++;
})
}
};
}).controller(“MyCtrl”,函数($scope){
$scope.model={someProperty:“此处某物”);
});
我在这里展示的是,你可以有一个变量,它具有来自子对象和父对象的双向绑定,但不要求子对象达到它的父对象才能获得属性。如果你在指令上方添加一个新的父对象,那么想要得到东西的倾向可能会变得疯狂

如果您在框中键入,它将更新控制器上的模型,这反过来又绑定到指令上的属性,因此它将在指令中更新。在指令链接函数中,它有一个监视设置,因此只要范围变量发生更改,它就会增加一个计数器


有关隔离作用域以及使用=@或&here之间的区别的详细信息:

如果要监视父作用域的属性,可以从父作用域使用
$watch
方法

//intead of $scope.$watch(...)
$scope.$parent.$watch('property', function(value){/* ... */});
编辑2016:
上述方法应该可以很好地工作,但它并不是一个干净的设计。尝试使用a或a,并将其依赖项声明为绑定。这将带来更好的性能和更干净的设计。

如果您希望在子范围内查看父范围变量,可以在
$watc上添加
true
作为第二个参数h
。这将在每次修改对象时触发手表

$scope.$watch("searchContext", function (ctx) {
                ...
            }, true);

非常确定您不能查看本地$scope之外的任何内容。但是您可以将$watch放在父$scope和$scope中。$将更改向下广播到子$scope。由于您的指令没有创建新的作用域,因此您应该能够
scope.$watch('data.overlytype',…)
。这里有一个例子说明了这一点。如果您认为需要使用
$parent
,那么我们需要查看更多的HTML,以确定HTML中的其他指令是否正在创建子作用域或隔离作用域。@Sharondio但我的子控制器通过扩展父控制器来运行。我不想在HTML中写入$watch父级。我想扩展父级,这样父级就不需要为特定于子级$scope的情况明确定义$watch。我想知道如何做到这一点。例如,子级作用域取决于它在父级作用域中看到的更改,但情况并非总是如此,因为其他子级不一定依赖于它,我也不知道如何做到这一点ant将特定于孩子的行为编码到家长中。我想让事情模块化,在孩子中包含特定于孩子的行为。啊哈!Petr Peller的答案似乎是解决方案,但对我来说仍然不起作用。当我发现其他人可能会发现这一点时,我会发回帖子。好吧,这是因为像
ngIf
这样的指令创建了孩子scopes,这是违反直觉的。Hrm,我根本没有数据属性。甚至不知道为什么我在这个指令中有一个子作用域,div在正常作用域内。有什么想法吗?哦,第一个参数是函数!我做了一个返回scope的函数。$parent.data.overlytype,它工作得很好。谢谢:)@Wes你不应该再重复了fer为$parent。您应该创建一个可以通过父范围的模型或其某些属性传递的变量。如果显示整个指令,则可以编辑此答案,以包括应如何通过对象。您可能正在使用隔离范围。您可以通过属性I从父范围传递所需的值'我将编辑答案,并提供完整的细节。感谢@NaorBiton,因为你说我正在组装一个小提琴来显示隔离作用域。仅供参考,你不需要定义函数来监视作用域属性,也不需要将
true
作为第三个参数(这就是小提琴的功能)。因此,你可以简单地编写:
scope.$watch('someData',function(){scope.count++;});
@MarkRajcok啊是的,我刚开始使用了错误的属性名,没有看到更新