问题描述
我有一个在本地运行的 AngularJS 1.4* 应用程序(还没有).此应用由 Laravel 5.1 后端 RESTFul API 提供服务.
我必须制作这个代表包裹旅行的应用程序.一个包由天组成,从0到N天不等.每天都有一个服务列表,范围从 0 到 N 个服务.还有酒店.
我的 Laravel 应用程序从中使用的 Web 服务器为我提供了一个预先设置的包,其中包含一个天数列表:每个天数都有一个服务列表和一个酒店数据(到目前为止未使用).在响应中,我有一个包的属性列表(现在无关紧要)和一个名为 days_info
的天数数组.该响应被放入我的 PackageController
上的 $scope.package
中.PackageController 还声明了一个名为 packageBlock
的指令,该指令包含天数列表和包的其他一些数据.
<package-days-block></package-days-block>
在 <package-days-block>
指令中,我有另一个每天遍历内部服务列表.
<服务块></服务块>
这就是问题开始的地方:令我意外的是,我的 ServiceController
中现在有一个 $scope.service
.因此,我开始根据自己的需要在 ServiceController
中通过 $scope.service
更改它.
$scope.service 有一个名为 service_id
的属性.我在它上面放了一个监听器/观察器,所以在 $scope.service.service_id 改变时,我要求另一个 service_table
(保存有关服务的信息,它基于用户之前选择或更改的service_id),并将其放入$scope.service.table
.
//服务控制器$scope.reloadServicesTable = function(service_id, service_day, date, paxes){MandatoryService.getServiceTable(service_id, service_day, date, paxes).然后(功能(服务数据){$scope.service.table = service_data;},...);
reloadServicesTable
在 service_id 变化的观察者上被调用.
//服务控制器$scope.$watch('service.service_id',//放置观察者以观察服务 ID 的变化.功能(新服务,旧服务){if( new_service === old_service )返回;$scope.reloadServicesTable($scope.service.service_id, $scope.service.service_day, $scope.day.date, $scope.package.paxes);});
问题从这里开始:当 service_id 只更改一次时,对服务表的请求会被调用两次.
为什么,上帝,为什么?!
在我的代码的另一部分,我从 PackageController 运行整个 days_info
数组并读取属性 price
的值> 在 service.table 中:service.table.price
.在那里,我意识到有两个范围:一个是我处理的,另一个是我没有奇怪的想法来自哪里!
如果我将 console.log($scope);
放在通过 days_info 运行的方法中,我会为每个请求获得两个范围.此方法位于 PackageController 上.
知道为什么会这样吗?
P.S.:这是我的第一个 AngularJS 应用程序,所以,如果我把一些基本的东西搞砸了,请放轻松......
正如一位同事在评论中指出的那样,我的问题不是很可重复.可悲的是,我不能只把我有疑问的部分放在这里,因为我一点也不知道问题出在哪里!(我知道这没有多大帮助)
我从 Chrome 控制台截取了一些屏幕截图:
首先,请求改变了 service_id
如您所见,每个请求每次都被调用两次.这不是一次性的./api/service/{id}...
是对服务表信息的调用./api/service/by_route/origin/...
返回从一个城市到另一个(或同一个)城市的服务列表.一个不干扰另一个.
另一个图像是来自 PackageController $scope 的 console.log 的输出,在 service_id 被更改时.
如您所见,有两个不同的范围.b
作用域是 r
作用域的儿子.r
作用域也在 service_id
?
总价调用从不同的地方调用了两次,如下图所示:
它可能会解决您的问题.就连我也遇到过和你说的一模一样的.
我的原因是,控制器再次初始化,其中编写了一个单独的 api 调用,用于最初加载页面.
也可能存在您在标记中分配了两次控制器的情况.
I have an AngularJS 1.4* application running locally (yet). This app is served by an Laravel 5.1 backend RESTFul API.
I have to make this app that represents a package trip. A package is composed by days, ranging from 0 to N days. Each day have a list of services, ranging from 0 to N services. And a hotel.
My web server, from which my laravel application consumes from, delivers me a pre-setted package, containing a list of days: each one with a list of services and a hotel data (unused so far). On the response I have a list of properties for the package (that don't matter for now) and an array of days, called days_info
. That response is being put in the $scope.package
, on my PackageController
. The PackageController also declares an directive called packageBlock
, that consists in a list of days, and some other data for the package.
<div ng-repeat="day in package.days_info" class='row'>
<div class='col-md-12'>
<package-days-block></package-days-block>
</div>
</div>
Inside <package-days-block>
directive, I have another to iterate through the list of services inside every day.
<div class='container-fluid' ng-repeat='service in day.services' ng-controller="ServiceController">
<service-block></service-block>
</div>
That's where the problem begins: to my undestandment, I now have a $scope.service
inside my ServiceController
. So, I started to change it on my need inside the ServiceController
through a $scope.service
.
The $scope.service has an attribute called service_id
. I put a listener/watcher on it, so at any time the $scope.service.service_id is changed, I ask for another service_table
(holds the informations about the services, it's based on the service_id previously choosen or changed by the user), and put it in the $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;
},
...
);
The reloadServicesTable
is called on the watcher for the service_id changes.
// 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);
}
);
The problem starts here: the request for the service's table is called twice when the service_id only changes once.
WHY, GOD, WHY?!
There's another part of my code where I, from the PackageController, run through the entire days_info
array and reads the value of an attribute price
inside the service.table: service.table.price
. In there, I realise that there's two scope's: the one I handling and the other that I have no FREAKING IDEA where it came from!
If I put an console.log($scope);
inside the method that runs through the days_info, I get two scopes for every request. This method is on the PackageController.
Any ideas why this is happening?
P.S.: It's my very first AngularJS application, so, take easy if I messed up on something basic...
EDIT:
As pointed out by an fellow on the comments, my question wasn't very reproducible. Sadly, I can't put here only the part I'm having doubts cause I don't have the slightest idea where the problem lies! (I know that this isn't much of help)
I took some screen shots from the Chrome Console:
First, the requestions fired on the change of the service_id
As you can see, every request is called twice everytime. This is not an one-time-thing. The /api/service/{id}...
is the call for the service's table information. The /api/service/by_route/origin/...
returns an list of services from one city to another (or the same). One does not interfere on the other.
The other image is the output from a console.log from the PackageController $scope, on the time that the service_id is being changed.
As you can see, there's two different scopes. And the b
scope is son of the r
scope. The r
scope is also calling the watcher on the service_id
?
The call for the sums price is been called twice from differente places, as you can see in the image below:
It may solve you issue. Even i had faced exactly the same as you are mentioning.
The reason for me was that, the controller was getting initialized again and there was a separate api call written in that, which was intended to load the page initially.
There can also be a scenario where you have assigned controller twice in the mark up.
这篇关于为什么我的观察者在同一个更改中被调用两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!