Angular $watch 只是父对象而不是它的多个子对象

Angular $watch just parent object instead of its multiple children

我有一个 div,列出了对象 POI = {"address":"Martinsicuro (TE), Italy", "phone":"+39 333 45657", "website':'http://mysite.it"} 的属性。服务拥有的对象 POI si。该指令的控制器具有从服务获取 POI 的函数 getPoi(),并将其 returns 传递给指令。

我现在的HTML是这样的:

<table ng-controller="Controller as ctrl">
    <tr> <!-- address -->
        <td>{{ctrl.getPoi().address}}</td>
    </tr>
    <tr> <!-- phone -->                   
        <td>{{ctrl.getPoi().phone}}</td>
    </tr>
    <tr> <!-- website -->
        <td>
            <a ng-href="{{ctrl.getPoi().website}}"> 
                {{ctrl.getPoi().website}}
            </a>
        </td>   
    </tr>
</table>

控制器

.controller('Controller', function(CurrentPoiService)
{

  this.getPoi = function()
    { return CurrentPoiService.POI; }
}

服务

.service('CurrentPoiService', function()
{

  this.POI = {"address":"Martinsicuro (TE), Italy", "phone":"+39 333 45657", "website':'http://mysite.it"}
}

通过这种方式,我添加了 3 个观察者。有没有办法只添加 1 个观察者,因为它是同一个父对象?这是一个 JSFiddle 谢谢

[更新 1] 这是(仍然不起作用)JSFiddle 使用@Charlie

提出的解决方案

[更新 2] 这是工作 JSFiddle

在你的控制器中尝试:

$scope.POI = ctrl.getPoi();

HTML :

<tr> <!-- address -->
    <td>{{POI.address}}</td>
</tr>
<tr> <!-- phone -->                   
    <td>{{POI.phone}}</td>
</tr>

正如 Claies 在评论中提到的,您永远不应该从 以这种方式通过函数查看。

在这种情况下,您可以使用 objectEquality 参数 truePOI 对象创建一个监视,以监视单个 $watch 中对象的属性。然后在侦听器中找到您的元素并以您想要的方式更改值。

$scope.$watch('POI', function(){

    //Assume that $scope.propertyIndex is the current property to display

    angular.element($document[0].querySelector("#myTd" + $scope.propertyIndex)).html(POI.address);
    angular.element($document[0].querySelector("#myTd" + $scope.propertyIndex)).html(POI.phone);
    //etc...

}, true);

这样你控制得更好。但请记住,如果 POI 是一个复杂的对象,则此方法不适用。

更新:

这是一个使用手表和工厂每秒显示一个随机数的工作示例。您应该能够从中学习并将其应用到您的项目中。

            myApp.controller('myController', function($scope, dataSource) {

                 $scope.poi = {rand: 0};    

                 $scope.$watch('poi', function() {
                    $('#rand').html($scope.poi.rand);
                 }, true);

                dataSource.open($scope);               

            });

            myApp.factory('dataSource', function($interval) {                

                return {                       
                            open: function(scope){
                                $interval(function() {
                                    scope.poi.rand = Math.random();
                                }, 1000);
                            }
                }    
            });