在Angularjs管理仅限客户状态
钥匙要点
-
AngularJ中的
- 查看模型可以具有仅限客户端状态,例如“动画启动”和“动画”或“拖动”和“删除”。使用Angular的$ Resource Service创建和保存视图模型时,可以管理此状态。
> >将状态变化逻辑封装在一个地方,例如注射服务,可以简化代码并减少错误,尤其是对于具有多重消费者的应用程序。
- >诸如功能包装之类的技术可用于保存和检索数据之前和之后进行不同或其他的事情。这可以增强$ Resource Service的功能。
- >将视图模型提取到注射服务中可以帮助扩展应用程序,尤其是具有复杂,实时更新的应用程序。观看和过滤等技术可用于管理状态变化并改善应用程序API的合成性。
- JavaScript框架(例如AngularJs)中的 >查看模型可能与服务器上的域模型不同 - 视图模型甚至不必在服务器上存在。因此,视图模型只能具有客户端状态,例如“动画开始”和“动画”或“拖动”和“掉落”。这篇文章使用Angular的$ Resource Service创建和保存视图模型时将集中于状态更改。
这种方法对于包含单个消费者的应用程序很好。想象一下,对于多个消费者,容易复制此代码的无聊和错误!但是,如果我们可以封装状态在一个地方更改逻辑怎么办?
>angular<span>.module('clientOnlyState.controllers') </span> <span>.controller('ArticleCtrl', function($scope, $resource, ArticleStates /* simple lookup */) { </span> <span>var Article = $resource('/article/:articleId', { articleId: '@id' }); </span> <span>var article = new Article({ id: 1, title: 'A title', author: 'M Godfrey' }); </span> article<span>.state = ArticleStates.NONE; // "NONE" </span> $scope<span>.article = article; </span> $scope<span>.save = function() { </span> article<span>.state = ArticleStates.SAVING; // "SAVING" </span> article<span>.$save(function success() { </span> article<span>.state = ArticleStates.SAVED; // "SAVED" </span> <span>}); </span> <span>}; </span> <span>});</span>
>让我们从将我们的文章资源推入注射服务中。当首次创建文章时,我们还将最微不足道的状态设置添加到无。
检索和保存怎么样?我们希望将文章作为$资源服务出现在消费者身上,因此它必须像一个人一样始终如一地工作。我在John Resig的出色著作《 JavaScript Ninja的秘密》中学到的一种技术在这里非常有用 - 功能包装。这是他的实现直接提升为可注射的角度服务。
>
angular<span>.module('clientOnlyState.services') </span> <span>.factory('Article', function($resource<span>, ArticleStates</span>) { </span> <span>var Article = $resource('/article/:articleId', { articleId: '@id' }); </span> <span>// Consumers will think they're getting an Article instance, and eventually they are... </span> <span>return function(data) { </span> <span>var article = new Article(data); </span> article<span>.state = ArticleStates.NONE; </span> <span>return article; </span> <span>} </span> <span>});</span>
angular<span>.module('clientOnlyState.services') </span> <span>.factory('wrapMethod', function() { </span> <span>return function(object<span>, method, wrapper</span>) { </span> <span>var fn = object[method]; </span> <span>return object[method] = function() { </span> <span>return wrapper.apply(this, [fn.bind(this)].concat( </span> <span>Array.prototype.slice.call(arguments)) </span> <span>); </span> <span>}; </span> <span>} </span> <span>});</span>
>
angular<span>.module('clientOnlyState.controllers') </span> <span>.controller('ArticleCtrl', function($scope, $resource, ArticleStates /* simple lookup */) { </span> <span>var Article = $resource('/article/:articleId', { articleId: '@id' }); </span> <span>var article = new Article({ id: 1, title: 'A title', author: 'M Godfrey' }); </span> article<span>.state = ArticleStates.NONE; // "NONE" </span> $scope<span>.article = article; </span> $scope<span>.save = function() { </span> article<span>.state = ArticleStates.SAVING; // "SAVING" </span> article<span>.$save(function success() { </span> article<span>.state = ArticleStates.SAVED; // "SAVED" </span> <span>}); </span> <span>}; </span> <span>});</span>
封装益处
>我们已经竭尽全力封装了控制器之外的状态变化,但是我们获得了什么好处?
>现在,我们的控制器可以利用通过旧状态通过的手表听众来设置消息。它也可以执行本地翻译,如下所示。
angular<span>.module('clientOnlyState.services') </span> <span>.factory('Article', function($resource<span>, ArticleStates</span>) { </span> <span>var Article = $resource('/article/:articleId', { articleId: '@id' }); </span> <span>// Consumers will think they're getting an Article instance, and eventually they are... </span> <span>return function(data) { </span> <span>var article = new Article(data); </span> article<span>.state = ArticleStates.NONE; </span> <span>return article; </span> <span>} </span> <span>});</span>
通过滤镜组合,灵丹妙药?
>
>类似以下内容是我的想法。表达的每个部分都可以重复使用。
angular<span>.module('clientOnlyState.services') </span> <span>.factory('wrapMethod', function() { </span> <span>return function(object<span>, method, wrapper</span>) { </span> <span>var fn = object[method]; </span> <span>return object[method] = function() { </span> <span>return wrapper.apply(this, [fn.bind(this)].concat( </span> <span>Array.prototype.slice.call(arguments)) </span> <span>); </span> <span>}; </span> <span>} </span> <span>});</span>
因此,我们需要对文章进行稍作修改:
angular<span>.module('clientOnlyState.services') </span> <span>.factory('Article', function($resource<span>, ArticleStates, wrapMethod</span>) { </span> <span>var Article = $resource('/article/:articleId', { articleId: '@id' }); </span> <span>wrapMethod(Article, 'get', function(original<span>, params</span>) { </span> <span>var article = original(params); </span> article<span>.$promise.then(function(article) { </span> article<span>.state = ArticleStates.NONE; </span> <span>}); </span> <span>return article; </span> <span>}); </span> <span>// Consumers will actually call $save with optional params, success and error arguments </span> <span>// $save consolidates arguments and then calls our wrapper, additionally passing the Resource instance </span> <span>wrapMethod(Article, 'save', function(original<span>, params, article, success, error</span>) { </span> article<span>.state = ArticleStates.SAVING; </span> <span>return original.call(this, params, article, function (article) { </span> article<span>.state = ArticleStates.SAVED; </span> success <span>&& success(article); </span> <span>}, function(article) { </span> article<span>.state = ArticleStates.ERROR; </span> error <span>&& error(article); </span> <span>}); </span> <span>}); </span> <span>// $resource(...) returns a function that also has methods </span> <span>// As such we reference Article's own properties via extend </span> <span>// Which in the case of get and save are already wrapped functions </span> <span>return angular.extend(function(data) { </span> <span>var article = new Article(data); </span> article<span>.state = ArticleStates.NONE; </span> <span>return article; </span> <span>}, Article); </span> <span>});</span>
最终结果并不那么漂亮,但仍然非常强大:
angular<span>.module('clientOnlyState.controllers') </span> <span>.controller('ArticleCtrl', function($scope<span>, Article</span>) { </span> <span>var article = new Article({ id: 1, title: 'A title', author: 'M Godfrey' }); </span> <span>console.log(article.state); // "NONE" </span> $scope<span>.article = article; </span> $scope<span>.save = function() { </span> article<span>.$save({}, function success() { </span> <span>console.log(article.state); // "SAVED" </span> <span>}, function error() { </span> <span>console.log(article.state); // "ERROR" </span> <span>}); </span> <span>}; </span> <span>});</span>
我们的控制器再次变得更倾斜,尤其是如果您认为可以将翻译拉出到可注射的服务中:
angular<span>.module('clientOnlyState.controllers') </span> <span>.controller('ArticleCtrl', function($scope<span>, Article, ArticleStates</span>) { </span> <span>var article = new Article({ id: 1, title: 'A title', author: 'M Godfrey' }); </span> <span>var translations = {}; </span> translations<span>[ArticleStates.SAVED] = 'Saved, oh yeah!'; </span> translations<span>['default'] = ''; </span> $scope<span>.article = article; </span> $scope<span>.save = function() { </span> article<span>.$save({}); </span> <span>}; </span> $scope<span>.$watch('article.state', function(newState<span>, oldState</span>) { </span> <span>if (newState == ArticleStates.SAVED && oldState == ArticleStates.SAVING) { </span> $scope<span>.message = translations[newState]; </span> <span>} else { </span> $scope<span>.message = translations['default']; </span> <span>} </span> <span>}); </span> <span>});</span>
结论
<span><span><span><p</span>></span>{{article.state | limitToTransition:"SAVING":"SAVED" | translate}}<span><span></p</span>></span></span>
>我提出了一种基于旧值和新值观察的替代方法。两者都是完全可以接受的技术 - 实际上,当我开始研究这篇文章时,我想到的是我的想法。过滤是在完成后附近发现的潜在改进。
>我很想看看我提出的技术是否可以帮助您扩展Angular应用程序。所有反馈都将在评论中得到极大的收获!
>在研究此帖子时创建的代码样本也可以在GitHub上找到。
>在Angularjs中管理客户状态的经常询问的问题
> $ state -provider在AngularJS中管理客户端状态的作用是什么?这是一项允许您为应用程序定义状态的服务。每个状态就整体UI和导航而言,对应于应用程序中的“位置”。 $ state -provider提供了路由不同视图的API。激活状态时,它可以通过Resolve属性解析一组数据。然后将这些数据注入控制器。>>我如何在$ state -provider中使用resolve属性?用于在激活状态之前解决一组数据。然后将这些数据注入控制器。解析属性是包含键值对的对象。关键是要注入控制器的依赖项的名称,该值是返回依赖关系值的函数。
>在Angularjs中使用UI-Router进行状态管理有什么好处?它允许嵌套视图和多个命名视图,这在较大的应用程序中可能非常有用。它还提供了基于状态的路由,它比AngularJS中的基于默认路由的路由更灵活,更强大。
>我如何在gangularjs中的状态之间过渡?在AngularJS中使用$ state.go()方法。该方法将状态的名称作为其第一个参数,而参数的可选对象是其第二个参数。参数对象可用于将数据传递到要过渡到的状态。
我可以在没有状态管理工具的情况下使用AngularJS吗?但是,随着您的应用程序的复杂性增长,如果使用UI-Router这样的工具,管理状态可能会变得越来越困难。使用状态管理工具可以帮助维持应用程序用户界面的一致性和可预测性。
>>在AngularJS中管理状态的一些共同挑战是什么?保持用户界面的一致性,跟踪应用程序状态的变化以及管理应用程序的行为。通过使用UI-Router等状态管理工具。
>我如何在$ state -provider中使用resolve属性?用于在激活状态之前解决一组数据。然后将这些数据注入控制器。解析属性是包含键值对的对象。关键是要注入控制器的依赖项的名称,该值是返回依赖关系值的函数。
>在Angularjs中使用UI-Router进行状态管理有什么好处?它允许嵌套视图和多个命名视图,这在较大的应用程序中可能非常有用。它还提供了基于状态的路由,它比AngularJS中的基于默认路由的路由更灵活,更强大。
>我如何在gangularjs中的状态之间过渡?在AngularJS中使用$ state.go()方法。该方法将状态的名称作为其第一个参数,而参数的可选对象是其第二个参数。参数对象可用于将数据传递到要过渡到的状态。
我可以在没有状态管理工具的情况下使用AngularJS吗?但是,随着您的应用程序的复杂性增长,如果使用UI-Router这样的工具,管理状态可能会变得越来越困难。使用状态管理工具可以帮助维持应用程序用户界面的一致性和可预测性。
>>在AngularJS中管理状态的一些共同挑战是什么?保持用户界面的一致性,跟踪应用程序状态的变化以及管理应用程序的行为。通过使用UI-Router等状态管理工具。
以上是在Angularjs管理仅限客户状态的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

深入探讨console.log输出差异的根源本文将分析一段代码中console.log函数输出结果的差异,并解释其背后的原因。�...

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。
