2016-05-31 180 views
2

我一直在使用角度ui路由器,一个问题不断出现。我希望你们中的一些人可以给我建议如何以一种干净而不危险的方式解决这个问题。Angular UI路由器:调用子状态控制器的功能

考虑以下情形:

enter image description here

在左边我有一个联系人列表侧面导航。一旦我点击一个联系人,所选联系人的详细信息将显示在app.contacts.details状态中。只要我选择了一个联系人,一些控件会出现在标题中,例如。 “编辑”和“删除”(将它们视为一个例子,实际上这些操作更复杂)。

理想情况下,这些按钮只会调用detailStateController的一个函数,例如。 detailStateController.delete()要删除当前选定的联系人或detailStateController.edit()以编辑选定的联系人(您会明白)。当然,这不起作用,因为编辑和删除按钮不在app.contacts.details状态的视图内,因此detailStateController不在其范围内。

我知道这可以通过广播事件来解决,但我想尽量避免使用事件。

你会如何解决这个问题?

任何意见非常感谢。

回答

0

我已经摆脱了这种风格,只需处理控制器与列表中的所有内容。如果您从详细信息控制器中删除项目或编辑父控制器中显示的字段,您最终必须更新列表控制器。当我按照你现在这样做的方式时,似乎我不得不跳过由于一个控制器中的细节和另一个控制器中的细节引起的许多额外的箍。我通常只有一个list属性,它是我的控制器上的一个数组,当前行属性是显示的完整记录。然后我使用ng-if来检查当前行并适当地显示。当单击一行时,我使用$ location.search更新网址,并在启动时检查$ location搜索以进行深度链接。这会导致单个控制器的体积稍大,但比2个控制器的组合还要小。如果我只处理几个字段,那么我会在列表中包含所有字段。如果有大量数据,当列表中的当前项目被更改为获取currentRow的数据并更新currentRow时,我会进行服务调用。

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 
     }); 
    } 
}]); 
0

我个人喜欢在这样的情况下创建以下结构。

路由器规定:

  • app.contacts.index - 对于含有详细/列表视图工具栏
  • app.contacts.list - 对于列表
  • ​​- 对于细节

控制器(为每个国家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 
}