当我创建新的DOM元素时,ng-model不起作用

时间:2015-05-11 09:54:04

标签: angularjs angularjs-scope

当我创建一个新的DOM元素(超出角度)时,angular不会控制它。为什么呢?

例:

<html ng-app="gemStore">
  <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
    </head>
  <body ng-controller="StoreController as store">
    <button onclick="changeDom();">CreateDomElementWithDataBinding</button>
    <input type='text' ng-model='store.bright'/>
    <div id='placeNewElement'>
    </div>
    <script type="text/javascript">
      angular.module('gemStore',[]).controller('StoreController', function(){
    	  this.name = 'diamont';
    	  this.bright = 3;
      });
      
      var changeDom = function(){
    	  document.getElementById('placeNewElement').innerHTML = "<input type='text' ng-model='store.name'/>";
      };
    </script>
  </body>
</html>

这里,初始DOM是使用与scope.bright数据模型进行数据绑定的输入创建的。 单击按钮时,将创建一个新元素,使用ng-model与scope.name进行数据绑定。 但是当创建新的DOM元素时,angular不会“管理”其元素(不显示scope.name值,不会将典型的角度类(ng-valid等)放到元素中。)

我搜索了很多,我无法解决它:-( 我试着让scope.apply()上传模型,但这似乎不是问题(因为angular不知道这个新元素)。

寻求帮助! ; - )

霍尔迪阿

4 个答案:

答案 0 :(得分:1)

使用管理DOM树的惯用方法(也就是说,不要在角度下修改它)

<html ng-app="gemStore">
  <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
    </head>
  <body ng-controller="StoreController as store">
    <button ng-click="store.showNameField = true">CreateDomElementWithDataBinding</button>
    <input type='text' ng-model='store.bright'/>
    <input type='text' ng-model='store.name' ng-if='store.showNameField' />
    <script type="text/javascript">
      angular.module('gemStore',[]).controller('StoreController', function(){
    	  this.name = 'diamont';
    	  this.bright = 3;
          this.showNameField = false;
      });
      
    </script>
  </body>
</html>

答案 1 :(得分:0)

您处理新元素的方法是错误的。您可以使用角度指令实现此目的,并与指令共享相同角度控制器的范围。这将在运行时更新DOM。 请看一下这个fiddle example。在这里我添加了一个文本框并动态添加了一个新文本框,该文本框与第一个文本框的内容具有相同的范围,并且它在角度范围内。

<section ng-app="myApp" ng-controller="MainCtrl">
    <addbuttonsbutton></addbuttonsbutton>
    <input type='text' ng-model='store'/>
    <div id="space-for-buttons"></section>
</section>

var myApp = angular.module('myApp', []);

function MainCtrl($scope) {
    $scope.count = 0;
    $scope.store = "";
}

//Directive that returns an element which adds buttons on click which show an alert on click
myApp.directive("addbuttonsbutton", function(){
    return {
        restrict: "E",
        template: "<button addbuttons>Click to add buttons</button>"
    }
});

//Directive for adding buttons on click that show an alert on click
myApp.directive("addbuttons", function($compile){
    return{
        link: function(scope, element, attrs){
        element.bind("click", function(){
            angular.element(document.getElementById('space-for-buttons')).append($compile("<input type='text' ng-model='store' ng-init='scope.store'/>")(scope));
        });
        }
    };
});

希望这有帮助。

答案 2 :(得分:0)

谢谢Lalit。 我将您的代码粘贴了一些工作更改(可能对搜索此解决方案的人有用)。

<html>
  <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
    </head>
  <body>
    <section ng-app="myApp" ng-controller="MainCtrl">
      <addbuttonsbutton></addbuttonsbutton>
      <input type='text' ng-model='store'/>
      <div id="space-for-buttons"></div>
    </section>
    
    <script type="text/javascript">
        
        var myApp = angular.module('myApp', []).controller('MainCtrl', function($scope) {
            $scope.store = "something";
        });
        
        //Directive that returns an element which adds buttons on click which show an alert on click
        myApp.directive("addbuttonsbutton", function(){
            return {
                restrict: "E",
                template: "<button addbuttons>Click to add buttons</button>"
            }
        });
        
        //Directive for adding buttons on click that show an alert on click
        myApp.directive("addbuttons", function($compile){
            return{
                link: function(scope, element, attrs){
                element.bind("click", function(){
                    angular.element(document.getElementById('space-for-buttons')).append($compile("<input type='text' ng-model='store'/>")(scope));
                });
                }
            };
        });
    </script>
  </body>
</html>

对我来说不是:-(因为我正在寻找一些可以改变新DOM元素创建方式的东西(可能是不可能的:-S)。

答案 3 :(得分:0)

我在angularJs google group

找到了Kevin Shay的答案

示例代码的解决方案是:

<html ng-app="gemStore">
  <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
    </head>
  <body ng-controller="StoreController as store">
    <button ng-click="recognizeNewElements();" onclick="changeDom();">CreateDomElementWithDataBinding</button>
    <input type='text' ng-model='store.bright'/>
    <div id='placeNewElement'>
    </div>
    <script type="text/javascript">
      angular.module('gemStore',[]).controller('StoreController', function($scope, $compile){
    	  this.name = 'diamont';
    	  this.bright = 3;
    	  $scope.recognizeNewElements = function(){
    	      var placeNewElement = angular.element(document.getElementById('placeNewElement'));
    	      $compile(placeNewElement.contents())($scope);
    	  };
      });
      
      var changeDom = function(){
    	  document.getElementById('placeNewElement').innerHTML = "<input type='text' ng-model='store.name'/>";
      };
    </script>
  </body>
</html>

非常感谢所有浪费时间帮助我的人!