angularjs - 通过 angularjs 模型查找字段

标签 angularjs angular-ngmodel

我能以某种方式找到与给定的 angularjs 模型对应的字段吗?我知道,可能有多个字段与单个变量对应,或者没有,但这不是问题。

例如,有一个输入 ng-model=users[2].name,我想要一个采用字符串 "users[2].name" 的方法,并且返回 DOM 元素。

我不需要太快,因为我希望它用于某种用户输入的演示,例如,如果用户应该填写名称字段,我将(鼠标模拟)覆盖移动到它并以编程方式填充它。硅

我可以通过 jquery 来做到这一点,但这相当麻烦,因为它几乎不像选择器input[ng-model="user[0].name"]那么简单。它通常隐藏在 ng-repeat="user in users" 中,并且深几个级别。或者更糟糕的是,混合使用 ng-repeat-startng-repeat-end

更改 users[2].name 然后查找更改后的 DOM 元素的解决方案可能也可以。

我创建了一个plunk希望能展示出我想要的东西。

最佳答案

我添加这个答案是因为它确实有效,与我原来的答案不同。此外,这是一种非常不同的方法,因此我不想将其附加到该方法上。

Caveat: this works if your ng-model expression has a dot, otherwise the prototypical inheritance chain doesn't exist to propagate the temporary change.

>>The Plunk

概述

首先,我们装饰 ng-model指令以跟踪所有 ng-model在应用程序中。这些模型存储在myModels中大批。然后我们循环myModels寻找所有评估出我们正在寻找的值的模型并将它们插入 possibleMatches大批。最后,我们更改目标值并循环possibleMatches以确定哪一个实际上发生了变化。

代码:

angular.module('find_by_model', [])

.constant('myModels', [])

.config(function($provide, myModels) {
  window.myModels = myModels; // just for debugging

  $provide.decorator('ngModelDirective', function($delegate) {

    var directive = $delegate[0];

    var compile = directive.compile;

    directive.compile = function(tElement, tAttrs) {
      var link = compile.apply(this, arguments);
      tElement.append('<div>Added in the decorator</div>');
      return function(scope, elem, attrs) {
        link.apply(this, arguments);
        v = scope.$eval(tAttrs.ngModel);
        myModels.push({scope: scope, elem:elem,
          val: function() {
            return scope.$eval(tAttrs.ngModel);
          },
        }); 
      }; 
    };

    return $delegate;
  });
})

.factory('finder', function (myModels) {
  function findElem($scope, path) {
    var originalVal = $scope.$eval(path),
        possibleMatches = [],
        result = null;

    angular.forEach(myModels, function (model) {
      if (angular.equals(model.val(), originalVal)) possibleMatches.push(model);
    });

    // temp change: the blah property is arbitrary
    try {
      var newVal = $scope.$eval(path + " = " + JSON.stringify({ val: path, blah: 'changed'}) );
    } catch(e) {
      return null;
    } 

    // find it: note: this could be made more efficient with a breaking loop
    angular.forEach(possibleMatches, function (model) {
      if (angular.equals(model.val(),newVal)) result = model;
    });

    // reset
    $scope.$eval(path + " = " + JSON.stringify(originalVal));

    return result && result.elem;
  }

  return {
    findElem: findElem
  }
})

这是你如何使用它(假设你已经注入(inject) finder ):

  $scope.expressionToFind = "m.top[0].name";

  var el = finder.findElem($scope, $scope.expressionToFind);
  if (el) 
    angular.element(el).css('outline', '1px solid red');
  else
    alert('not found');

关于angularjs - 通过 angularjs 模型查找字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24368861/

相关文章:

javascript - 一键单击按钮下的两个功能

javascript - 在已解决的 promise 中使用 angular.extend 绑定(bind)数据的正确方法

javascript - ng-model 异步函数的奇怪行为

javascript - 在选择中为 ng-model 分配一个对象

html - ng-model 的 Angularjs 动态名称

javascript - 以 Angular 2 设置路线

angularjs - Ckeditor - 光标位置始终在 setData 之后到达开头

javascript - Karma - 未知提供商错误 : menuFactoryProvider <- menuFactory

angularjs - 无法清除表格

angularjs - 如何根据ng-change更新ng-class?