简体   繁体   English

ng-model未从控制器更新到视图

[英]ng-model not updated from controller to view

in this plunk I have made a demo for my problem which I'm facing from last week. 在这个小问题上,我为上周面对的问题做了一个演示。 Code snippet contains bootstrap tab which includes two different pages - page1 and page2 and they are using same controller. 代码段包含引导程序选项卡,该选项卡包含两个不同的页面-page1page2,并且它们使用同一控制器。 Page1 has ng-repeat and when we click on option from there then It's hit in controller function vm.edit(selected_variable) and Page2 has a simple input box that has a ng-model="vm.name" . Page1具有ng-repeat,当我们从那里单击选项时,它将在控制器函数vm.edit(selected_variable)中命中,而Page2具有一个简单的输入框,其中包含ng-model =“ vm.name” My problem is that ng-name is not updated or replaced with the value when vm.edit function updates it. 我的问题是ng-name在vm.edit函数更新时不会更新或替换为该值。 I can solve this problem using rootScope but I don't want to use rootScope. 我可以使用rootScope解决此问题,但是我不想使用rootScope。 I just want to avoid rootScope and want to use vm . 我只想避免rootScope并想使用vm

My code example: 我的代码示例:

page1: 第1页:

<div ng-controller="appCtrl as vm">
  <div>
    <ul>
      <li ng-repeat="list in vm.list track by $index">
        <button type="button" class="btn-u btn-brd btn-u-none" ng-click="vm.edit(list, $index)" data-toggle="tab" href="#page2">
                    {{ list.name }}
                </button>
      </li>
    </ul>
  </div>
</div> 

page2: 第2页:

<div ng-controller="appCtrl as vm">
  <input type="text" ng-model="vm.name">
</div>

Controller: 控制器:

vm.edit = function(listItem, index) {
    vm.name = listItem.name;

    console.log(vm.name);
  };

The edit function updates vm.name in page1 but it doesn't reflect in page2. 编辑功能会更新第1页中的vm.name ,但不会反映在第2页中。 Couldn't solve this issue, Any Ideas? 无法解决这个问题,有什么想法吗?

In order to communicate between controllers, you can make use of $broadcast event to transfer data. 为了在控制器之间进行通信,可以利用$ broadcast事件传输数据。 Here is the edited Plunker . 这是经过编辑的“ Plunker”

Inside vm.edit function register broadcast and listen to the event in the same controller: vm.edit函数内部注册广播并在同一控制器中监听事件:

vm.edit = function(listItem, index) {
  $rootScope.$broadcast("vm name: changed", listItem.name);
};
$scope.$on("vm name: changed", function(evt, obj){
  vm.name = obj;
});

Also don't forget to add $rootScope dependency to your controller: 同样不要忘记将$ rootScope依赖项添加到您的控制器中:

app.controller('appCtrl', function($scope, $rootScope) {...});

Note: Here $rootScope is used only to trigger event but not to store the value. 注意:此处$ rootScope仅用于触发事件,而不用于存储值。

page1.html page1.html

<div ng-controller="appCtrl">
<div>
<ul>
  <li ng-repeat="listitem in list track by $index">
    <button type="button" class="btn-u btn-brd btn-u-none" ng-click="edit(listitem, $index)" data-toggle="tab" href="#page2">
      {{ listitem.name }}
    </button>
  </li>
</ul>
</div>
</div>

page2.html page2.html

<div ng-controller="appCtrl">
<div>
<ul>
  <li ng-repeat="listitem in list track by $index">
    <button type="button" class="btn-u btn-brd btn-u-none" ng-click="edit(listitem, $index)" data-toggle="tab" href="#page2">
      {{ listitem.name }}
    </button>
  </li>
</ul>
</div>
</div>

script.js 的script.js

var app = angular.module('app', []);
app.controller('appCtrl', function($scope, $compile) {
var vm = this;
// List
$scope.list = [
  {
    'id': 1,
    'name': 'afroza'
  },
  {
    'id': 2,
    'name': 'yasmin'
  }
];
// edit function
$scope.edit = function(listItem, index) {


    $scope.name = listItem.name;

    //this one is very important
    $compile(angular.element( document.querySelector('#name')))($scope);

};

});

Please check Demo 请检查演示

page1 and page2 and they are using same controller - they are not using same controller. page1 and page2 and they are using same controller -它们没有使用相同的控制器。 They are using two different instances of same controller. 他们正在使用同一控制器的两个不同实例。

If you want to use same Controller instance, you can do ng-controller="appCtrl as vm" on parent. 如果要使用相同的Controller实例,则可以对父节点执行ng-controller="appCtrl as vm" Otherwise, you can use rootScope or service 否则,您可以使用rootScopeservice

Demo 演示

You should just add two components, say the PageComponent and the PageContainerComponent. 您应该只添加两个组件,例如PageComponent和PageContainerComponent。 The PageContainerComponent is put in the masterpage that contains the tabs. PageContainerComponent放置在包含选项卡的母版页中。 The PageComponent requires the PageContainerComponent as a parent and contains the logic of the page. PageComponent需要PageContainerComponent作为父级,并包含页面的逻辑。

Then you can simply put anything you want to share in the PageContainerComponent, since the PageComponent has access to it. 然后,您可以将要共享的任何内容简单地放在PageContainerComponent中,因为PageComponent可以访问它。 If you can even bind things directly to the PageContainerComponent in the page views providing you make the PageContainerComponent available as a variable on the PageComponent. 如果您甚至可以将内容直接绑定到页面视图中的PageContainerComponent上,前提是您使PageContainerComponent可以作为PageComponent上的变量使用。

Something like this: 像这样:

angular.module('app').component('pageContainerComponent', {
    controller: function() {
        this.someProperty = 'yay';
    },
    template: '<div ng-transclude></div>'
});

angular.module('app').component('page1Component', {
    controller: function() {
        // This controller will now have a property tabsCtrl
        // With the controller for pageContainerComponent
    },
    controllerAs: 'vm',
    template: '<div>Page 1 content {{vm.tabsCtr.someProperty}}</div>',
    require: {
       tabsCtrl: '^myTabs'
    },
});

Usage should be something like this 用法应该是这样的

<page-container-component>
    <div class="someTabClass">
         <page1-component></page1-component>
    </div>
</page-container-component>

This is all from the top of my head, so there may be a typo here or there, but I hope it helps anyway. 这些都是从我的头上来的,所以这里或那里可能有错别字,但是我希望无论如何都会有帮助。

Edit 编辑

Oh, almost forgot, you can ofcourse use the same controller function for a page1Component and a page2Component, to make several pages with the same controller logic, but different views. 哦,差点忘了,您当然可以对page1Component和page2Component使用相同的控制器功能,以使多个页面具有相同的控制器逻辑,但视图不同。 I don't really see the point though, since the 'shared logic' should be in the pageContainerComponent anyway. 不过,我并没有真正理解这一点,因为“共享逻辑”无论如何都应该在pageContainerComponent中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM