我一直在使用角度ui-router,一个问题不断出现。我希望你们中的一些人可以给我建议如何以干净,非黑客的方式解决这个问题。
考虑以下情况:
在左侧,我有一个带有联系人列表的侧面导航栏。点击联系人后,所选联系人的详细信息将显示在app.contacts.details
状态。一旦我选择了联系人,标题中就会显示一些控件,例如。 "编辑"和"删除" (仅以它们为例,实际上这些动作更复杂)。
理想情况下,这些按钮只会调用detailStateController的函数,例如。 detailStateController.delete()
删除当前选定的联系人,或detailStateController.edit()
编辑所选联系人(您明白了)。当然这不起作用,因为编辑和删除按钮不在app.contacts.details
州的视图内,因此detailStateController
不在其范围内。
我知道这可以通过广播事件来解决,但我想尽可能避免使用事件。
你会如何解决这个问题?
非常感谢任何建议。
答案 0 :(得分:1)
工厂是单身人士,可用于跨控制器共享数据和功能。你可以这样写:
app.factory("DataService", ["$http", function($http){
var contacts = [];
return {
//sharing functions
postItem: function(url, item) {
return $http({
url: url,
method: 'POST',
data: item
});
},
putItem: function(url, item) {
return $http({
url: url,
method: 'PUT',
data: item
});
},
deleteItem: function(url, item) {
return $http({
url: url,
data: item,
method: 'DELETE'
});
},
setContacts = function(contacts) {
contacts = contacts;
},
addContacts = function(contact) {
contacts.push(contact);
},
deleteContact = function(contact) {
var idx = this.contacts.indexOf(contact);
contacts.splice(idx, 1);
}
};
}]);
然后,在你的控制器中:
app.controller("ContactDetailsCtrl", ["$scope", "DataService", function($scope, DataService){
$scope.deleteContact = function() {
DataService.deleteItem('path/to/delete', { contactId: 123 }).then(function(response) {
//remove from client-side array once it's removed form db
DataService.deleteContact(contact);
}).catch(function(response){
//an error occurred
});
}
}]);
答案 1 :(得分:0)
我已经离开了这种风格,只需从控制器和列表中处理所有内容。如果从详细控制器中删除项目或编辑父控制器中显示的字段,则最终还是必须更新列表控制器。当我按照你现在这样做的方式做这件事时,似乎我必须跳过很多额外的箍,这是因为一个控制器中的细节和另一个控制器中的列表。我通常只有一个list属性,它是我的控制器上的数组和当前行属性,它是显示的完整记录。然后我使用ng-if检查当前行并正确显示。单击一行时,我使用$ location.search来更新URL,并在启动时检查$ location搜索以进行深层链接。这导致单个控制器有点大,但它仍然小于2个控制器的总和。如果我只处理几个字段,我会在列表中包含所有字段。如果有大量数据,我会在更改列表中的当前项目以获取currentRow的数据并更新currentRow时进行服务调用。
答案 2 :(得分:0)
我个人喜欢在这种情况下创建以下结构。
路由器声明:
app.contacts.index
- 用于包含详细信息/列表视图的工具栏app.contacts.list
- 列表app.contacts.detail
- 详情控制器(对于每个州的resp):
function IndexCtrl($scope)
{
$scope.contact = {}; // For containing the selected contact
$scope.contacts = []; // List of contacts also on the parent view
// Define Detail View functions here
$scope.edit = Edit;
$scope.delete = Delete;
// Perform operations on $scope.contact/$scope.contacts
function Edit() {}
function Delete() {}
}
function DetailCtrl($scope)
{
$scope.contact = $scope.$parent.contact = $scope.$parent.contacts[id]; // This way we work with the parent contact defined in IndexCtrl
}
function ListCtrl($scope, Contacts)
{
$scope.contacts = $scope.parent.contacts = Contacts.list(); // Contacts Service to retrieve the contact list
}