这个架构在Angular 1.2及以上版本下仍然有效吗?
Is this architecture still valid under Angular 1.2 and above
有很多使用$resource的代码示例。我遇到了这个,它的代码布局非常清楚:https://github.com/apotry/stockwatch
我喜欢这个例子是因为:
- 它与Rails后端交互,这就是我使用Angular的方式
- 使用$resource
- 正在使用非休息路由(ohlc)
- 代码很干净
调用定义的函数非常简单,如下面的控制器代码所示,但是在工厂中嵌入保存是一个好主意吗?
我的问题是:既然Angular 1.2+包含了承诺,这种类型的代码仍然有效吗?这段代码如何响应错误状态?
这里定义了资源
app.factory('Stock', ['$resource', function($resource) {
function Stock() {
this.service = $resource('/api/stocks/:stockId', {stockId: '@id'}, {'update': { method: 'PUT' }});
};
Stock.prototype.all = function() {
return this.service.query();
};
Stock.prototype.delete = function(stId) {
return this.service.remove({stockId: stId});
};
Stock.prototype.create = function(attr) {
return this.service.save(attr);
};
Stock.prototype.update = function(attr) {
return this.service.update(attr);
};
Stock.prototype.ohlc = function(stId) {
return $resource('/api/stocks/:stockId/ohlc', {stockId: '@id'}).get({stockId: stId});
}
return new Stock;
}]);
下面是一个删除、创建和自定义路由(ohlc)的示例:
$scope.requestOHLC = function (stockid) {
return Stock.ohlc(stockid);
}
$scope.createStock = function() {
$scope.fetchYahooFinanceData($filter('uppercase') ($scope.newCompany["symbol"])).then(function(result) {
$scope.error = false;
$scope.stocks.push(Stock.create(result));
$scope.newCompany = '';
}, function(error) {
$scope.error = true;
});
};
$scope.deleteStock = function(id, idx) {
Stock.delete(id);
$scope.stocks.splice(idx, 1);
};
编辑
我试图找出一个简单明了的实践,在angular中使用基于$resource的休息路由。
与上面的代码不同,但基于它。假设下面的代码使用的服务与上面的工厂基本相同。在本例中,我调用一个REST资源来创建一个新资源(rails表项),然后将新创建的id传递给另一个调用。注意,createPanelHeader引用了$scope.selector.paneldata。primer3_parameter_id作用域变量。我也不确定这是不是一个好的做法。
我发现这不会工作,除非我使用$promise。然后是,但这看起来有点复杂。我的思路对吗?
// Section: Create Panel header
createPrimer3Parameter = function() {
primer3_parameter = Primer3Parameter.create().$promise.then(function(primer3_parameter){
$scope.selector.paneldata.primer3_parameter_id = primer3_parameter.id;
createPanelHeader();
}, function() {
alert('Error creating primer3parameter');
})
};
我真的只是想找出一个简单的方法,从Rails API访问REST资源,最多1层嵌套。我想我遗漏了一些东西,因为它似乎非常困难。
到目前为止,我听到的是不要使用$resource,即使在1.2下。我应该使用原始的$http或Restangular。
同时,似乎有一些1.2版本的变化会影响到Restangular。这个解决方案对我来说有点像一个hack:
https://github.com/mgonto/restangular using-values-directly-in-templates
我并不是真的100%清楚,所以我发布了一个赏金:https://bountify.co/write-an-angular-service-for-these-rails-routes-using-restangular
这种类型的代码仍然有效并被认为是一种良好的实践吗?
此代码是有效的,但在1.2.0-rc3中被认为已弃用。它将在angular 1.2和1.3的所有版本中工作,但不包括1.3.0-beta10,其中自动取消承诺。
$scope.stocks.push(Stock.create(result));
在上面的行中,您已经在$scope
上创建了一个promise对象数组。然后在index.html.erb中,你通过stock
迭代器直接引用承诺:
<li ng-repeat="stock in stocks">
<div id='symbol'>
{{stock.symbol}}
</div>
未被弃用的处理承诺的方式不允许你像这样直接绑定到承诺。
这段代码如何响应错误状态?
应用程序在这里处理错误:
}, function(error) {
$scope.error = true;
});
:
<div ng-show="error">
There was a problem with the Yahoo Finance API. Please try again later.
</div>
对于错误处理,你没有直接绑定承诺,所以这在所有版本的angular中都能很好地工作。
更好的方法?
首先,搁置stockwatch示例中的javascript目录结构。然后,遵循这个目录结构。最后,将Restangular集成到你的项目中。创建一个stockModel
工厂,在内部实例化一个Restangular
对象,但返回将在承诺解析后填充的对象(model
)。不要在分部中绑定承诺,而要绑定未填充的结果对象。
.factory('stocksModel', function (Restangular) {
var model = {};
var rest_stocks = Restangular.all('stocks');
model.doSomethingRESTful = function (...) {
// return a promise in case the controller needs it
return rest_carts.some_restangular_method(...)
.then(function() {
model.some_data_which_was_acquired_RESTfully = ...;
});
};
return model;
});
在你的控制器中:
$scope.stocks = stocksModel;
在你的局部:
{{stocks.some_data_which_was_acquired_RESTfully}}
直言不讳
。如果可能的话,我会改进代码,使其更易于维护,并与Angular保持同步。让我解释一下为什么这是个好主意……
你为什么让你的生活如此艰难?
Angular是一个很棒的框架,它可以让你用简单的解决方案来处理相当复杂的问题。Angular的阴暗面是,如果你不走寻常路,很容易过度设计一个解决方案。Angular暴露了很多内部的东西,所以与其走简单的路线,不如尝试一下(也很有趣!)"成长的烦恼"
我相信你正在处理的问题是由于Angular作为一个成熟的项目所经历的成长的痛苦。许多辅助项目如雨后春笋般涌现,以修复那些已经被堵塞的漏洞。
Rails和Angular,快速的朋友
所以我是基于我是如何在Angular中使用Rails的。这些例子是从一个不打算去任何地方的宠物项目中提取出来的。不幸的是,这都是在咖啡脚本,所以希望不会造成你的问题。它的结构是我发现Rails最适合的,同时保持了Angular的精神和乐趣。
* app/assets/javascripts
* app
* project_name_app.js.coffee.erb
* controllers
* controllers.js
* directives
* directives.js
* filters
* filters.js
* resources
* resources.js
* services
* services.js
Rails的资产管道使用包含:
的application.js
来包装一切://= require app/project_name_app
在app/project_name_app.js.coffee。其次,它会加载包含
的所有目录#= require_self
#= require app/controllers/controllers
#= require app/directives/directives
#= require app/filters/filters
#= require app/resources/resources
#= require app/services/services
最后,每个子目录js (controllers.js, directives.js, filters.js, resources.js, services.js)只是加载该目录下的所有内容:
//= require_tree .
在这个设置中,project_name_app.js.coffee.erb
首先被加载,设置Angular、依赖项和应用配置。然后加载控制器、指令、过滤器等。其中一个好处是,由于require_tree
,添加到子目录中的新javascript会自动包含。
保持$resource的简单性
最好的$资源是RESTFUL。这意味着它是示例URL,功能根据请求的http方法而更改。缺点是,如果您有不同的url,则可能需要多个资源。users_resource.js.coffee:
中的示例angular.module("DeployerApp.resources").factory "Users", ($resource) ->
$resource "/users.json", {},
index:
method: "GET"
isArray: true
type: "User"
angular.module("DeployerApp.resources").factory "User", ($resource) ->
$resource "/users/:user_id.json", {},
show:
method: "GET"
update:
method: "PUT"
angular.module("DeployerApp.resources").factory "CurrentUser", ($resource) ->
$resource "/users/current.json", {},
show:
method: "GET"
要获取所有用户,调用Users.index()
。要获得单个用户,可以调用User.show( user_id: 1 )
。最后,一个方便的$资源I,经常使用,以获得当前认证的用户,CurrentUser.show()
。
非常直接,易于阅读,避免了必须有厚模型。每个User $资源可以单独测试。
Angular已经准备好了
如果你在处理多个响应时有一些复杂的杂耍行为,你真的只需要开始与$promise
打交道。我发现将成功和错误回调传递给$资源更简单,例如:
CurrentUser.show success = (user) ->
$scope.currentUser = user
, error = (data,status) ->
# redirect to login
变量名有助于使代码更具可读性,没有它们,coffeescript函数定义就像是混在一起了。
越简单越好
您不需要担心$资源的$promise.then
,允许您整理内容。
- JS编译器/包管理器,用于版本控制
- jQuery-2.1.1.min.js或最新版本jQuery-2.13.min.js不会't支持'@
- Chrome加载旧版本的Javascript文件
- 如何使用js将SNAPSHOT内部版本号转换为3位数的整数
- 如何有效地将游戏数据存储在URL查询字符串中
- 如何使用Node.js最有效地解析网页
- jquery代码在Mozilla中有效,但在其他浏览器上无效
- 为什么jQuery 1.8不能在IE8和InternetExplorer9中使用?(截至2012年9月的IE9最新版本)
- 有效形式-始终只显示1个错误[角度]
- 如何设置jsfiddle's的javascript版本
- Javascript袖珍参考,第121页:这是怎么回事;猴子补丁”;方法应该有效
- 单击仅在第二次单击后有效
- 什么'是在asp.net MVC中将本地化的resources.resx文件转换为javascript文件的有效
- 砌体在移动浏览器(chrome)上不起作用,并且仅在Chrome桌面版本上有效,如果我重新加载(ctrl + f5)页面
- JavaScript 中更有效的 ID 计算器版本
- 为什么许多Jquery动画或效果在Internet Explorer的较低版本中有效
- 这个JavaScript函数和显示命令示例的更有效版本
- 如何有效地使用两个版本的JQuery
- 这个架构在Angular 1.2及以上版本下仍然有效吗?
- 角度ng重复和过滤器错误(版本1.1.5有效,1.2.15有错误)