钥匙要点
-
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>$ Resource Services
>让我们从将我们的文章资源推入注射服务中。当首次创建文章时,我们还将最微不足道的状态设置添加到无。
检索和保存怎么样?我们希望将文章作为$资源服务出现在消费者身上,因此它必须像一个人一样始终如一地工作。我在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>考虑$ scopes,指令和过滤器构成应用程序的API。 HTML视图消耗此API。 API的合成性越大,重用的潜力就越大。过滤器可以改善新观看与旧观看的合成性吗?
通过滤镜组合,灵丹妙药?
>
>类似以下内容是我的想法。表达的每个部分都可以重复使用。
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 1.3开始,过滤器可以使用$ stateful属性,但是由于Angular无法根据输入参数的值调用过滤器,因此强烈劝阻其使用。因此,我们将将状态参数传递给Limittotransition(以前的状态)并翻译(可用翻译)。
因此,我们需要对文章进行稍作修改:
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>></p></span>{{article.state | limitToTransition:"SAVING":"SAVED" | translate}}<span><span></span>></span></span></span>>将视图模型提取到注射服务中有助于我们扩展应用程序。这篇文章中给出的示例很简单。考虑一个允许货币对交易的应用程序(例如,英镑至USD,EUR到GBP等)。每个货币对代表一个产品。在这样的应用程序中,可能会有数百种产品,每种产品都会收到实时价格更新。价格更新可能高于当前价格。该应用程序的一部分可能会关心连续两次更高的价格,而另一部分可能关心刚刚降低的价格。能够观察这些价格变化状态极大地简化了应用程序的各个部分。
>我提出了一种基于旧值和新值观察的替代方法。两者都是完全可以接受的技术 - 实际上,当我开始研究这篇文章时,我想到的是我的想法。过滤是在完成后附近发现的潜在改进。
>我很想看看我提出的技术是否可以帮助您扩展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中文网其他相关文章!

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

10款趣味横生的jQuery游戏插件,让您的网站更具吸引力,提升用户粘性!虽然Flash仍然是开发休闲网页游戏的最佳软件,但jQuery也能创造出令人惊喜的效果,虽然无法与纯动作Flash游戏媲美,但在某些情况下,您也能在浏览器中获得意想不到的乐趣。 jQuery井字棋游戏 游戏编程的“Hello world”,现在有了jQuery版本。 源码 jQuery疯狂填词游戏 这是一个填空游戏,由于不知道单词的上下文,可能会产生一些古怪的结果。 源码 jQuery扫雷游戏

本教程演示了如何使用jQuery创建迷人的视差背景效果。 我们将构建一个带有分层图像的标题横幅,从而创造出令人惊叹的视觉深度。 更新的插件可与JQuery 1.6.4及更高版本一起使用。 下载

Matter.js是一个用JavaScript编写的2D刚体物理引擎。此库可以帮助您轻松地在浏览器中模拟2D物理。它提供了许多功能,例如创建刚体并为其分配质量、面积或密度等物理属性的能力。您还可以模拟不同类型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流浏览器。此外,它也适用于移动设备,因为它可以检测触摸并具有响应能力。所有这些功能都使其值得您投入时间学习如何使用该引擎,因为这样您就可以轻松创建基于物理的2D游戏或模拟。在本教程中,我将介绍此库的基础知识,包括其安装和用法,并提供一

本文演示了如何使用jQuery和ajax自动每5秒自动刷新DIV的内容。 该示例从RSS提要中获取并显示了最新的博客文章以及最后的刷新时间戳。 加载图像是选择

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

Dreamweaver Mac版
视觉化网页开发工具

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

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

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),