文本框上的ng-change高效/单触发

时间:2019-04-26 07:53:31

标签: javascript html angularjs

假设我在角度控制器中具有以下数组:

somelist = [ 
             { name: 'John',  dirty: false },
             { name: 'Max',   dirty: false },
             { name: 'Betty', dirty: false }
           ];

我想在视图中进行ng-repeat,并为每个记录生成可编辑的字段:

<div ng-repeat="i in somelist">
     <input type="text" ng-model="i.name"/>
</div>

如果有人编辑文本框(模型),我将如何有效地将字段标记为肮脏?

我意识到我可以在文本字段上使用ng-change,但是,每当用户在文本框上进行单个更改(输入键)时,都会触发该ng-change,从而不必要地增加了呼叫量。这种方式,我想念吗?

2 个答案:

答案 0 :(得分:0)

使用JavaScript ...
*编辑:如果textareas没有其他“更改”事件要运行,则可以尝试内联onchange事件,并在运行一次后替换其值。只是使onchange="once(this)"成为这个主题-onchange="" *在后台。该代码仍将保留在您的HTML中。演示:

(在Angular中也存在inputkeyup事件...

function once(e){
  e.style.color="red";
  e.onchange = "";
  
  //just demo... remove this.
  const d = document.getElementById('demo');
  d.innerText = Number(d.innerText) + 1;
 }
<textarea class="moo" onchange="once(this)">Change me!</textarea>
<textarea class="moo" onchange="once(this)">Me too!</textarea>
<textarea class="moo" onchange="once(this)">And me!</textarea>
<br><br>
Triggered times: <span id="demo">0</span>


运行一次eventListener函数(不是真的):

let once = [];//creating empty array
const moo = document.getElementsByClassName('moo');//getting all textareas
for(let i = 0; i < moo.length; i++ ){//looping, to add 'change' event to each element
  once.push(1);//adding '1' to array 'i' times. Here it will look like [1,1,1];
  moo[i].addEventListener('change', function(){
    if(once[i]==0){return}//if array element equals 0 = return and don't run the function
    this.style.color = "red";
    once[i] = 0;//after triggered = making array element = 0;
    
    //just demo... remove this.
    const d = document.getElementById('demo');
    d.innerText = Number(d.innerText) + 1;
  });
}
<textarea class="moo">Change me!</textarea>
<textarea class="moo">Me too!</textarea>
<textarea class="moo">And me!</textarea>
<br><br>
Triggered times: <span id="demo">0</span>

*函数每次仍在工作...但是立即返回,比“完全”运行更好。

答案 1 :(得分:0)

要提高效率,请使用int并消除双向绑定,例如::,以减少 watchers 的数量:

ng-model

然后,在您的控制器中:

<div ng-repeat="i in ::somelist"> <input type="text" value="{{i.name}}" ng-blur="$emit('nameChanged', i)"/> </div>

然后是一个快速,简单的函数,假设您具有以下条件,则使用$scope.$on('nameChanged', (event, i) => updateName(i));i.id用相应的ID更新名称。

i.name

说明

如果不打算从列表中添加/删除人员,则可以在$scope.someList = [ { id: 1, name: 'John' }, { id: 2, name: 'Max' }, { id: 3, name: 'Betty }'上使用::,也称为一次性绑定,提高效率。这样可以避免设置观察者

另外,通过设置value = {someList,您可以有效地设置从控制器到DOM的单向绑定,而不是双向的,这意味着不会在{{i.name}}周期的每个循环中检查输入,但是对模型的任何更改都会更新DOM。

只是一个主意,可以随心所欲地进行变化,例如降低模糊度并使用单个按钮立即更新所有更改过的字段。

除非您还像$digest一样从value="{{i.name}}"删除观察者,然后在收到事件后手动更新DOM,否则您将获得更高的效率。