javascript AngularJS - 将参数传递给控制器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31077942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS - Pass parameters into Controller?
提问by Gareth Lewis
I'm trying to create a simple blog website using AngularJS. I'm just starting out, so what I'm thinking my not be the best way to do this, so any alternative suggestions are welcome.
我正在尝试使用 AngularJS 创建一个简单的博客网站。我刚刚开始,所以我认为我不是最好的方法,所以欢迎任何其他建议。
I have a controller.js file with two blog controllers. One to display a list of blog posts, and the other that displays the post content by including an HTML file.
我有一个带有两个博客控制器的 controller.js 文件。一个显示博客文章列表,另一个显示通过包含 HTML 文件的文章内容。
controller.js
控制器.js
myAppControllers.controller('BlogListCtrl', ['$scope', '$http', function ($scope, $http) {
$http.get('articles/articles.json').success(function (articles) {
$scope.articles = articles;
});
}]);
myAppControllers.controller('BlogPostCtrl', ['$scope', '$routeParams', function ($scope, $routeParams) {
$scope.includeFile = 'articles/' + $routeParams.blogPostId + '.html';
}]);
articles.json
文章.json
[
{
"id": "test-article-one",
"title": "Test Article one",
"author": "Gareth Lewis",
"datePosted": "2015-06-23",
"summary": "This is a test summary"
},
{
"id": "test-article-two",
"title": "Test article two",
"author": "Gareth Lewis",
"datePosted": "2015-06-23",
"summary": "This is a test for article two"
}
]
app.js
应用程序.js
when('/blog', {
templateUrl: 'partials/blog-articles.html',
controller: 'BlogListCtrl'
}).
when('/blog/:blogPostId', {
templateUrl: 'partials/blog-post.html',
controller: 'BlogPostCtrl'
}).
blog-post.html
博客文章.html
<ng-include src="'partials/header.html'"></ng-include>
<!-- Want to add title, author, datePosted information here... -->
<article class="content">
<ng-include src="includeFile"></ng-include>
</article>
This blog listings work fine. When I click into a blog post, it also serves up the content from the HTML file OK as well. However, I want to be able to reuse the title
, author
and datePosted
properties from the selected article in the blog-post.html partial view. What's the best way to do this? Would I need to pass them to the Controller somehow to then pass to the view? I don't really want to pass these as routeParams. Or would I need to do a $http.get on articles.json and iterate through to find the selected article and then pass the property values back to the view?
这个博客列表工作正常。当我点击进入一篇博客文章时,它也会提供 HTML 文件中的内容。但是,我希望能够在 blog-post.html 部分视图中重用所选文章中的title
,author
和datePosted
属性。做到这一点的最佳方法是什么?我是否需要以某种方式将它们传递给控制器然后传递给视图?我真的不想将这些作为 routeParams 传递。或者我是否需要在articles.json 上执行$http.get 并遍历以找到所选文章,然后将属性值传递回视图?
Thanks for the help.
谢谢您的帮助。
回答by Dalorzo
This is maybe a common question in angular. What you have to understand is that Scopeis defined per controller... In order to share data across controller you still have the option to use $scope.$parent
or $rootScope
to link controllers but I would use those carefully.
这可能是 angular 中的一个常见问题。您必须了解的是,范围是按控制器定义的...为了在控制器之间共享数据,您仍然可以选择使用$scope.$parent
或$rootScope
链接控制器,但我会谨慎使用这些。
It is better to use Angular Serviceswhich are based on singleton patterns therefore you can use them to share information between controllers and I think it will be a better approach.
最好使用基于单例模式的Angular 服务,因此您可以使用它们在控制器之间共享信息,我认为这将是一种更好的方法。
I found that this has been previously discussed and here are some good examples:
我发现这之前已经讨论过,这里有一些很好的例子:
回答by Mateus Leon
You said that suggestions are welcome, so here it goes.
你说欢迎提出建议,所以就这样吧。
1 - Transport all your Blog logic to a service;
1 - 将所有博客逻辑传输到服务;
2 - Provide the data on resolving routes. This is a better approach to handle errors during the load time, 404s, and so on. You can provide a listener to $routeChangeError
and deal with it there;
2 - 提供解决路线的数据。这是在加载时间、404 秒等期间处理错误的更好方法。你可以提供一个监听器$routeChangeError
并在那里处理它;
3 - On the service declared below, you have the methods to call your data and a method to retrieve the list cached on the service:
3 - 在下面声明的服务上,您有调用数据的方法和检索缓存在服务上的列表的方法:
// services.js
myAppServices
.service('BlogService', ['$http', '$q', function ($http, $q) {
var api = {},
currentData = {
list: [],
article: {}
};
api.getSaved = function () {
return currentData;
};
api.listArticles = function () {
var deferred = $q.defer(),
backup = angular.copy(currentData.list);
$http.get('articles/articles.json')
.then(function (response) {
currentData.list = response;
deferred.resolve(response);
}, function () {
currentData.list = backup;
deferred.reject(reason);
});
return deferred.promise;
};
api.getArticle = function (id) {
var deferred = $q.defer(),
backup = angular.copy(currentData.article),
path = 'articles/' + id + '.html';
$http.get(path, {
cache: true
})
.then(function (response) {
currentData.article = {
path: path,
response: response
};
deferred.resolve(currentData.article);
}, function (reason) {
currentData.article = backup;
deferred.reject(currentData.article);
});
return deferred.promise;
};
return api;
}]);
The BlogService.getSaved()
will retrieve the stored data, made after each call.
在BlogService.getSaved()
将检索存储的数据,每次通话后作出的。
I've made a method to call the ng-include
path too, so you can verify if it exists, with cache === true
, the browser will keep a copy of it, when calling it again on the view. A copy of the response of the blog article is made too, so you can access its path and the response whenever you need.
我也做了一个调用ng-include
路径的方法,所以你可以验证它是否存在cache === true
,当在视图上再次调用它时,浏览器将保留它的副本。还制作了博客文章响应的副本,因此您可以随时访问其路径和响应。
On the controllers below, they were adaptated to supply the current needs:
在下面的控制器上,它们经过调整以满足当前的需求:
// controller.js
myAppControllers
.controller('BlogListCtrl', ['$scope', 'articles',
function ($scope, articles) {
$scope.articles = articles;
/* OTHER STUFF HERE */
}
])
.controller('BlogPostCtrl', ['$routeParams', '$scope', 'article' 'BlogService',
function ($routeParams, $scope, article, BlogService) {
// On `article` dependency, you have both the original response
// and the path formed. If you want to use any of it.
$scope.includeFile = article.path;
// To get the current stored data (if any):
$scope.articles = BlogService.getSaved().list;
// Traverse the array to get your current article:
$scope.article = $scope.articles.filter(function (item) {
return item.id === $routeParams.id;
});
/* OTHER STUFF HERE */
}
]);
And the route declarations were changed to load the data when resolving the routes.
并且在解析路由时更改了路由声明以加载数据。
// app.js
$routeProvider
.when('/blog', {
templateUrl: 'partials/blog-articles.html',
controller: 'BlogListCtrl',
resolve: {
articles: ['BlogService', '$routeParams', function (BlogService, $routeParams) {
return BlogService.listArticles();
}]
}
})
.when('/blog/:id', {
templateUrl: 'partials/blog-post.html',
controller: 'BlogPostCtrl',
resolve: {
article: ['BlogService', '$routeParams', function (BlogService, $routeParams) {
return BlogService.getArticle($routeParams.blogPostId);
}]
}
})
回答by Alexandre Mendes
You can use a global scope to set this data, or you can use service to communicate between the controllers. There is a lot of ways to resolve this problem read a little bit more about services in the link bellow and see if you can find how to resolve your problem.
您可以使用全局范围来设置此数据,也可以使用服务在控制器之间进行通信。有很多方法可以解决此问题,请阅读以下链接中有关服务的更多信息,看看您是否能找到解决问题的方法。