angularjs – 使用量角器与循环

前端之家收集整理的这篇文章主要介绍了angularjs – 使用量角器与循环前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
循环索引(i)不是我在循环中使用量角器时期望的.

症状:

Failed: Index out of bound. Trying to access element at index:’x’,but there are only ‘x’ elements

要么

Index is static and always equal to the last value

我的代码

  1. for (var i = 0; i < MAX; ++i) {
  2. getPromise().then(function() {
  3. someArray[i] // 'i' always takes the value of 'MAX'
  4. })
  5. }

例如:

  1. var expected = ['expect1','expect2','expect3'];
  2. var els = element.all(by.css('selector'));
  3. for (var i = 0; i < expected.length; ++i) {
  4. els.get(i).getText().then(function(text) {
  5. expect(text).toEqual(expected[i]); // Error: `i` is always 3.
  6. })
  7. }

要么

  1. var els = element.all(by.css('selector'));
  2. for (var i = 0; i < 3; ++i) {
  3. els.get(i).getText().then(function(text) {
  4. if (text === 'should click') {
  5. els.get(i).click(); // fails with "Failed: Index out of bound. Trying to access element at index:3,but there are only 3 elements"
  6. }
  7. })
  8. }

要么

  1. var els = element.all(by.css('selector'));
  2. els.then(function(rawelements) {
  3. for (var i = 0; i < rawelements.length; ++i) {
  4. rawelements[i].getText().then(function(text) {
  5. if (text === 'should click') {
  6. rawelements[i].click(); // fails with "Failed: Index out of bound. Trying to access element at index:'rawelements.length',but there are only 'rawelements.length' elements"
  7. }
  8. })
  9. }
  10. })
这是因为量角器使用承诺.

Read 07000

当基础值准备就绪时,Promises(即element(by …),element.all(by …))执行它们的函数.这意味着所有的承诺是首先安排的,然后当结果准备就绪时运行当时的功能.

当你运行这样的东西:

  1. for (var i = 0; i < 3; ++i) {
  2. console.log('1) i is: ',i);
  3. getPromise().then(function() {
  4. console.log('2) i is: ',i);
  5. someArray[i] // 'i' always takes the value of 3
  6. })
  7. }
  8. console.log('* finished looping. i is: ',i);

发生什么是getPromise().then(function(){…})在承诺准备好之前立即返回,而不执行那个函数.所以首先循环遍历3次,调度所有的getPromise()调用.然后,随着承诺的解决,相应的运行.

控制台看起来像这样:

  1. 1) i is: 0 // schedules first `getPromise()`
  2. 1) i is: 1 // schedules second `getPromise()`
  3. 1) i is: 2 // schedules third `getPromise()`
  4. * finished looping. i is: 3
  5. 2) i is: 3 // first `then` function runs,but i is already 3 now.
  6. 2) i is: 3 // second `then` function runs,but i is already 3 now.
  7. 2) i is: 3 // third `then` function runs,but i is already 3 now.

那么,你如何在循环中运行量角器?
一般解决方案是关闭.见JavaScript closure inside loops – simple practical example

  1. for (var i = 0; i < 3; ++i) {
  2. console.log('1) i is: ',i);
  3. var func = (function() {
  4. var j = i;
  5. return function() {
  6. console.log('2) j is: ',j);
  7. someArray[j] // 'j' takes the values of 0..2
  8. }
  9. })();
  10. getPromise().then(func);
  11. }
  12. console.log('* finished looping. i is: ',i);

但这不是很好阅读.幸运的是,您还可以使用量角器函数filter(fn),get(i),first(),last()以及预期修补的承诺来处理这个事实.

回到前面提供的例子.第一个例子可以重写为:

  1. var expected = ['expect1','expect3'];
  2. var els = element.all(by.css('selector'));
  3. for (var i = 0; i < expected.length; ++i) {
  4. expect(els.get(i).getText()).toEqual(expected[i]); // note,the i is no longer in a `then` function and take the correct values.
  5. }

第二和第三个例子可以重写为:

  1. var els = element.all(by.css('selector'));
  2. els.filter(function(elem) {
  3. return elem.getText().then(function(text) {
  4. return text === 'should click';
  5. });
  6. }).click();
  7. // note here we first used a 'filter' to select the appropriate elements,and used the fact that actions like `click` can act on an array to click all matching elements. The result is that we can stop using a for loop altogether.

换句话说,量角器有许多方法来迭代或访问元素i,以便您不需要使用for循环,而我.但是如果你必须使用for循环,我可以使用闭包解决方案.

猜你在找的Angularjs相关文章