javascript 如何在 div(或类似的东西)上使用 ngChange

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30946624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 12:59:22  来源:igfitidea点击:

How to use ngChange on a div (or something similar)

javascriptangularjs

提问by Get Off My Lawn

I had an input that had ng-changeon it, then I changed it to a contenteditablediv, so I can have a little more control over what I can do with the input. But the thing is that when I changed from an input to a div, I am no longer able to use ng-change. What can I do obtain the same effect/result?

我有一个输入ng-change,然后我将它更改为一个contenteditablediv,这样我就可以更好地控制我可以用输入做什么。但问题是,当我从输入更改为 div 时,我无法再使用ng-change. 我该怎么做才能获得相同的效果/结果?

Here is how I am using it in my template:

这是我在模板中使用它的方式:

<div class="form-control" ng-model="search" ng-change="searchChanged()" contenteditable="true">{{seach}}</div>

回答by PSL

Inorder to support ng-modelwith ng-changefor anything other than form element, you would need to create a custom directive. For example a simple implementation as below directive named contenteditable(much similar to angular having internal directives for input, formetc), have it require ng-modeland on keyupevent set the viewvalue and render the ng-model. When you setViewValuefor the ng-modeland values are different than prev value angular will evaluate the ng-changeexpression.

序支持ng-modelng-change比表单元素其他任何东西,你需要创建一个自定义的指令。例如,一个简单的实施方式,如下命名指令contenteditable(多类似于角具有内部指示为inputform等等),具有它需要ng-model和对keyup事件设置viewvalue并呈现NG-模型。当您setViewValueng-modeland 值与 prev 值不同时,angular 将评估ng-change表达式。

.directive('contenteditable', function() {
      return {
        require: 'ngModel',
        restrict: 'A',
        link: function(scope, elm, attr, ngModel) {

          function updateViewValue() {
            ngModel.$setViewValue(this.innerHTML);
          }
          //Binding it to keyup, lly bind it to any other events of interest 
          //like change etc..
          elm.on('keyup', updateViewValue);

          scope.$on('$destroy', function() {
            elm.off('keyup', updateViewValue);
          });

          ngModel.$render = function(){
             elm.html(ngModel.$viewValue);
          }

        }
    }
});

and do:

并做:

<div class="form-control" type="search" 
      ng-model="seach" ng-change="searchChanged()" 
      contenteditable="true"></div>

angular.module('app', []).controller('ctrl', function($scope) {
  $scope.seach = "Initial";
  $scope.searchChanged = function() {
    console.log('changed', $scope.seach);
  }
}).directive('contenteditable', function() {
  return {
    require: 'ngModel',
    restrict: 'A',
    link: function(scope, elm, attr, ngModel) {

      function updateViewValue() {
        ngModel.$setViewValue(this.innerHTML);
      }

      //Or bind it to any other events
      elm.on('keyup', updateViewValue);

      scope.$on('$destroy', function() {
        elm.off('keyup', updateViewValue);
      });

      ngModel.$render = function() {
        elm.html(ngModel.$viewValue);
      }

    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  Edit
  <div class="form-control" type="search" ng-model="seach" ng-change="searchChanged()" contenteditable="true"></div>
  {{seach}}
</div>

回答by Donal

ng-change only works on an input not a div. Try ng-click.

ng-change 仅适用于输入而不适用于 div。尝试 ng-click。

For an example of implementing a custom directive to bind a model to a contenteditable div, see here.

有关实现自定义指令以将模型绑定到 contenteditable div 的示例,请参见此处

回答by Ashot

You can't add ng-change to div element because it is not data source. But you can write custom directive to handle custom ng-change implementaion.

您不能将 ng-change 添加到 div 元素,因为它不是数据源。但是您可以编写自定义指令来处理自定义 ng-change 实现。

回答by Ashot

// usage
<div ng-model="val" onChange="fireEvent(val)"></div>

// implementation
angular.module('app',[]).directive('contenteditable', [function() {
 return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {

        function read() {
            ngModel.$setViewValue(element.html());
        }

        ngModel.$render = function() {
            element.html(ngModel.$viewValue || '');
        };

        element.bind('blur keyup change', function() {
            scope.$apply(function(){
               read();
               attrs.onChange(ngModel.$viewValue)
            });
        });
      }
  };
}]);

Try this one. It is my own implementation.

试试这个。这是我自己的实现。

回答by Duncan

Assuming your directive link function looks like this:

假设您的指令链接函数如下所示:

link: function ($scope, element, attrs, ngModel) {

then you can attach a viewChangeListener to ngModel.

然后您可以将 viewChangeListener 附加到 ngModel。

ngModel.$viewChangeListeners.push(function() {
  $scope.$eval(attrs.ngChange);
});

回答by rahim.nagori

ng-change only works if an input is changed from not from js. So ng-change is only applicable to input tags. Applying custom directive to a div might solve your problem.

ng-change 仅在输入不是从 js 更改时才有效。所以 ng-change 只适用于输入标签。将自定义指令应用于 div 可能会解决您的问题。