为什么我的观察者会在同一个变化中被叫两次?

Den*_*aga 8 angularjs angularjs-scope angularjs-ng-repeat

我有一个在本地运行的AngularJS 1.4*应用程序.此应用程序由Laravel 5.1后端RESTFul API提供.

我必须制作代表包旅行的这个应用程序.包裹由天组成,范围从0到N天.每天都有一系列服务,范围从0到N服务.还有一家酒店.

我的laravel应用程序从中获取的Web服务器为我提供了一个预先设置的包,其中包含一个日期列表:每个包含服务列表和酒店数据(到目前为止未使用过).在响应中,我有一个包的属性列表(现在无关紧要)和一个天数组,称为days_info.那个回应正在$scope.package我的身上PackageController.该PackageController也声明了一个指令packageBlock,它由在天的列表,以及软件包中某些数据.

<div ng-repeat="day in package.days_info" class='row'>
    <div class='col-md-12'>
        <package-days-block></package-days-block>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

在内部<package-days-block>指令中,我有另一个在每天内遍历服务列表.

<div class='container-fluid' ng-repeat='service in day.services' ng-controller="ServiceController">
    <service-block></service-block>
</div>
Run Code Online (Sandbox Code Playgroud)

这就是问题开始的地方:对我来说,我现在有一个$scope.service内心ServiceController.于是,我开始改变它在我需要在里面ServiceController通过$scope.service.

$ scope.service具有称为属性service_id.我把一个监听器/观察器放在上面,所以在任何时候更改$ scope.service.service_id,我要求另一个service_table(保存有关服务的信息,它基于之前由用户选择或更改的service_id),以及把它放进去$scope.service.table.

// ServiceController
$scope.reloadServicesTable = function(service_id, service_day, date, paxes){
    MandatoryService.getServiceTable(service_id, service_day, date, paxes)
    .then(
        function(service_data) {
            $scope.service.table = service_data;
        }, 
        ...
    );
Run Code Online (Sandbox Code Playgroud)

reloadServicesTable被要求观察者对的service_id变化.

// ServiceController
$scope.$watch(
    'service.service_id', // Places the watcher to watch the changes on the service's ID.
    function(new_service, old_service) {
        if( new_service === old_service )
            return; 

        $scope.reloadServicesTable($scope.service.service_id, $scope.service.service_day, $scope.day.date, $scope.package.paxes);

    }
);
Run Code Online (Sandbox Code Playgroud)

问题从这里开始:当service_id只更改一次时,将调用服务表的请求两次.

上帝啊,这到底是为什么?!

我的代码的另一部分是我从PackageController运行整个days_info数组并读取priceservice.table 中的属性值:service.table.price.在那里,我意识到有两个范围:我处理的那个,另一个我没有它来自哪个FREAKING IDEA!

如果我console.log($scope);在通过days_info运行的方法中放入一个内部,我会为每个请求获得两个范围.这个方法在PackageController上.

任何想法为什么会这样?

PS:这是我的第一个AngularJS应用程序,所以,如果我搞砸了一些基本的东西,那就太容易了......

编辑:

正如一位评论员所指出的,我的问题不是很可重复.可悲的是,我不能只把我怀疑的部分放在这里,因为我没有任何想法,问题出在哪里!(我知道这没有多大帮助)

我从Chrome控制台拍摄了一些屏幕截图:

首先,请求触发了service_id的更改

请求服务更改日志(按路径名排序)

如您所见,每次请求都会被调用两次.这不是一次性的事情.这/api/service/{id}...是对服务表信息的调用.在/api/service/by_route/origin/...返回从一个城市到另一个(或相同)服务的列表.一个人不会干涉另一个人.

另一个图像是来自PackageController $ scope 的console.log的输出,在service_id被更改时.

PackageController的范围

如您所见,有两个不同的范围.和b范围的子r范围.该r范围还呼吁观察者service_id

对于总和价格的调用是从不同的地方调用两次,如下图所示:

在PackageController上为sumPrices方法调用Stack

Luk*_*sac 3

它可能会解决你的问题。即使我也遇到过和你提到的一模一样的情况。

  1. 对我来说,原因是控制器再次初始化,其中写入了一个单独的 api 调用,旨在最初加载页面。

  2. 还可能存在这样的情况:您在标记中分配了两次控制器。