我添加这个答案是因为它确实有效,不像我原来的答案。此外,这是一种非常不同的方法,所以我不想只是将它附加到那个方法上。
警告:如果您的 ng-model 表达式有一个点,则此方法有效,否则不存在用于传播临时更改的原型继承链。
概述
首先,我们装饰ng-model
指令以便跟踪ng-model
应用程序中的所有 s。这些模型存储在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
}
})
这里是你如何使用它(假设你已经注入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');