角度控制器功能在电流控制器外部

时间:2016-05-11 16:49:42

标签: angularjs

我的Angular 1.x应用程序中有4个控制器:

  1. houseController
  2. apartmentController
  3. addressController
  4. contactInfoController
  5. 使用 addressController & contactInfoController 我更新了房屋或公寓的地址和联系信息。

    我的工作方式如下:

    <div ng-controller="houseController" ng-init="getHouseInformation()>
        {{house.contact_info.email}}
        {{house.contact_info.mobile_phone_number}}
    
        <a ng-controller="contactInfoController" ng-click="showContactInfoEdit(house.contact_info.id)">Edit</a>
    </div>
    

    当在contactInfoController中成功更新联系人信息时,我想更新houseController中的房屋信息getHouseInformation()(阅读:对API进行新的调用以获取更新的信息)。

    由于我有一个以上(以及将来甚至更多)房屋/公寓/ ......控制器,我需要有一个坚实的方法来如何刷新&#39;这些公寓,房屋的范围......在飞行中。

    在我的案例中,最好的解决方案是什么?

    编辑:

    我的范围看起来像这样:

    // in houseController
    
    $scope.house = {
        id : 1,
        title : "House title",
        contact_info : {
            email: '',
            mobile_phone_number : ''
        }
    }
    
    // in apartmentController
    
    $scope.apartment = {
        id : 1,
        title : "Apartment title",
        contact_info : {
            email: '',
            mobile_phone_number : ''
        }
    }
    
    // in contactInfoController
    
    $scope.contact_info : {
        email: '',
        mobile_phone_number : ''
    }
    

    因此,在更新联系信息范围时,我并没有直接改变房屋范围......希望这会有所帮助。

3 个答案:

答案 0 :(得分:1)

我不同意你在这里得到的其他建议 - 指令可以帮助你用你的数据智能地操纵DOM,但不一定在范围之间共享它,这就是你所要求的。正如我在Slack上写给你的那样,你似乎在寻找的是一个服务,它将包含你的所有数据(在其中声明或链接到外部文件或API),然后注入每个需要访问的控制器数据。这是服务的主要用途之一!

对于后人,这是我在Slack写给你的内容: &#34; ...您目前正在创建无法通信的无关对象 - 为什么要这样做?它们的范围不同。你实际上没有从Angular中获得任何用处,并且可以使用vanilla Javascript:)

我们的想法是在您的网络应用中使用共享的持久数据。 $ scope.anything永远不会在其范围之外进行通信,除非你绑定到范围之外的东西,比如服务。服务是从外部API中获取数据,还是仅仅是在Angular外部外部的对象模型(例如,在您的服务器/文件结构上),甚至是在服务本身内定义的数据没问题(虽然后者远非最佳做法) - 但是你需要在你的控制器/视图之间共享的局部范围之外持续存在的东西。

然后有几种方法可以连接点。一个非常常见(可能是最好的)设计模式是创建一个服务(NOT指令!我不知道为什么他们给你这个建议)封装了这些数据。所以,例如,

myApp.service(‘dataModel', function(){

$scope.houses = {}; //an object containing ALL the houses, each one containing ALL the apartments, each apt.containing ALL the contact info, etc. etc.

});

然后在您的控制器中传递dataModel服务,然后声明并链接本地范围&#39; reference&#39;它的相同对象,例如:

myApp.controller(‘buildingsView’, [dataModel, function(dataModel){

//and link to that service’s object locally:
$scope.houses = dataModel.houses;
}]);

然后,一旦你在一个视图/控制器中影响该模型,其他视图/控制器中的数据也会神奇地改变!

是角度方式:)

希望这是有道理的!

(为了澄清,这里有两个问题:通过向各种控制器注入相同的服务,使数据INTO成角度然后共享相同的对象。这就是服务的确切概念 - 它们是单身,这意味着只有一个副本存在于任何时间,如果它们被多次引用,它将永远是同一个对象,这就是为什么在一个地方操纵它会在另一个地方改变它。)&#34; < / p>

答案 1 :(得分:0)

将您的数据放在$ scope变量中,并让您的控制器在范围内观察此变量。触发事件后,您就可以按照自己的意愿行事。

$scope.houses = [];
$scope.$watch('houses', function(newValue, oldValue) {
// This is triggered when $scope.houses changes directly
// Add true as param to this function if you want to watch properties nested within the houses object
});

如果房屋在控制器内,请使用以下内容:

(在控制器中)

var self = this;
self.houses = [];
// This tells angular to watch the controller property houses instead of a scope variable
$scope.$watch(function(){return self.houses}, function(newValue, oldValue) {
// This is triggered when $scope.houses changes directly
// Add true as param to this function if you want to watch properties nested within the houses object
});

答案 2 :(得分:0)

我建议使用指令,然后更容易交换数据。这就是指令存在的原因。我尝试解释如何使用指令构建用例。假设您有一个控制器(houseController),并且对于每个子要求,您都可以创建一个指令。一个用于联系人,一个用于公寓,一个用于地址。然后在 houseController 中定义整个对象。您将所有必要的数据作为参数传递给指令,并且您可以从 houseController 或从指令内部访问它们,因为双向数据绑定。通过这种方式,您不必交换内容或调用更新功能。你只是调整对象。

你的HTML

<div ng-controller="houseController">
    <contact data="house.contact"></contact>
    <apartment data="house.apartment"></apartment>
    ...
</div>

house controller

$scope.house = {
  apartment:{
     floor: 1, 
     number:34,
     ...
  },
  contact:{
    id:2, 
    email:"peter@test.com", 
    mobile_phone_number:"123456789",
    ...
  },
  ...
}

联系指令

.directive('contact', function() {
  return {
    restrict: 'E',
    scope: {
      data: '='
    },
    link: function(scope, element, attrs) {
       scope.showContactInfoEdit = function(id){
          // do your stuff here
          scope.data.name = "Peter";
       }
    },
    templateUrl: 'contact.html'
  };
});

contact.html

 {{data.email}}
 {{data.mobile_phone_number}}
 <a ng-click="showContactInfoEdit(data.id)">Edit</a>

我做了一个plunkr:http://plnkr.co/edit/8tRMtgztaXRC3EKyQhcH?p=preview