【发布时间】:2014-03-17 17:05:54
【问题描述】:
我来自静态类型的面向对象背景 (C#),并且对 Angular 和 Javascript 不熟悉。我正在尝试使用 Angular 和 JQueryMobile 构建一个应用程序,并且面临服务的行为不像单例的情况 - 即即使它们已在一个控制器中初始化一次,服务中的属性也不会存储它们的任何状态当传递到另一个控制器或服务时设置为。此外,当我尝试调试如下所述的代码时,我遇到了一些意外行为:
我的设置:
- 我正在使用 JQueryMobile 单页模板,该模板将应用程序的所有页面作为 div 在同一个 html 页面上,并且使用“href="#DivName" 模式进行重定向
- 应用的每个 div(page) 都有一个关联的控制器和服务
- 控制器会根据要求注入多个服务,并且注入的服务应保持在其他控制器中初始化时的状态。
- 我没有使用路由和模板 - 整个 html 都在一个页面中
相关代码大纲如下:
HTML:
<div data-role="page" id="PageA" data-ng-controller="PageAController">
<!-- page content and UI elements-->
</div>
<div data-role="page" id="PageB" data-ng-controller="PageBController">
<!-- page content and UI elements-->
</div>
服务:
var App = angular.module('App', []);
App.service('serviceA', function () {
var propA;
//objectX is an array of objects with each object containing a hashtable and some other properties
propA = [{},{}]; //hardcoded value for objectX gets returned properly
return {
initialize: function(objectX){
propA = objectX; // Dynamically initialized objectX value is returned as "undefined" by the getPropA function below
},
getPropA: function () {
return propA;
}
};
});
App.service('serviceB', function (serviceA) {
var propB;
return {
initialize: function(){
propB = serviceA.getPropA(); //THIS DOES NOT WORK AS THE VALUE RETURNED IS UNDEFINED
},
processPropB: function () {
//logic for processing of propB
}
};
});
控制器:
App.controller('ControllerA', ['$scope', 'ServiceA',
function ($scope, ServiceA) {
$scope.UITriggeredAction = function(){
ServiceA.initialize(objectX);
};
}]);
//This controller gets invoked at a later point during the user interaction where ServiceA is supposed to be initialised and injected
App.controller('ControllerB', ['$scope', 'ServiceB', 'ServiceA',
function ($scope, ServiceB, ServiceA,) {
var returnedPropA = ServiceA.getPropA(); //THIS RETURNS UNDEFINED TOO
//process logic to use serviceB depending on valu of returnedPropA
}]);
问题:
在上面的 serviceA 代码中,如果我在返回块之前通过硬编码来初始化 propA 的值,则在执行 getPropA() 方法时会返回该值。请解释这是如何工作的。
我还想知道在 Angular 中调用 javascript 代码的顺序 - 我的理解是,当相关页面在浏览器中加载并且控制器代码依次调用时,Angular 运行时会调用适当的控制器函数服务方法。但是,如果我在不同的控制器和/或服务中有警报并加载页面,即使不应该调用页面或控制器/服务,警报也会立即显示。更奇怪的是,当实际的控制器或服务方法被执行时,警报并没有被执行。似乎所有控制器都在页面加载时执行。
请让我知道如何设置我的代码,以便我可以在不同的控制器中传递服务,而一旦在执行期间的任何地方初始化或更新,它们就不会丢失它们的状态。
谢谢, 山塔努
编辑:
我认为答案就在我的第二个问题中。对我来说 - 代码执行的控制流程并不清楚。以下是我认为的问题:
基本上,两个 Angular 控制器都在页面加载时由 Angular 运行时执行,而不是按照它们在应用程序中加载和使用的顺序执行 - 尽管这可能只是 JQMobile 的事情。
当对用户界面操作进行赋值操作时,服务中的相应变量设置成功。但是角度运行时不会重新评估所有控制器以确保新分配反映在所有控制器中。
所以另一个控制器继续返回它在初始化时设置的值 - 未定义。
但是,如果变量是在页面加载时设置的——那就是在初始化时返回的值与所需的值一起发生并且一切正常。
根据要求,我还在下面创建了一个简单的 plunk,以使用 cmets 显示上述要点: http://plnkr.co/edit/yBOL0P3ycsoNzVrydaMs
作为问题的解决方案,以下是我认为应该可行的方法:
以某种方式确保控制器仅在需要时初始化,而不是在页面加载时一次性初始化,以便可以根据前面操作中设置的状态进行初始化。我认为可以通过模板和路由来实现,这样只有在所需的路由和模板被称为 foe 时才会调用控制器。我不确定这是不是它的工作方式。
第二个选项是在设置控制器中发布事件并在需要时订阅它们以保持同步。这似乎是一种更好的方法。
如果可行,我会确认并发布答案。
请告诉我你的想法。
抱歉,帖子太长了:)
【问题讨论】:
-
这是一个很长的问题。也许尝试将其划分为不同的问题,并让 jsFiddle/plnkrs 来展示您的问题。
-
我怀疑你可能有错字。 JavaScript 区分大小写,因此 serviceA 与 ServiceA 不同。
-
这是直接复制/粘贴吗?
function ($scope, ServiceB, 'ServiceA',) {。不应该是:function ($scope, ServiceB, ServiceA) { -
@TheRocketSurgeon - 这不是直接复制/粘贴,而是已更正的错字。还添加了一个 plunker 示例 - 请查看。谢谢。
-
不确定它是否有帮助,但我为类似的问题做了一个代码笔:codepen.io/yakovkhalinsky/pen/LeirK
标签: javascript angularjs jquery-mobile