元の回答とは異なり、実際に機能するため、この回答を追加しています。また、これはかなり異なるアプローチであるため、単にそれに追加したくありませんでした。
警告:これは、ng-model 式にドットがある場合に機能します。そうでない場合、一時的な変更を伝達するためのプロトタイプの継承チェーンが存在しません。
概要
まず、アプリ内の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
}
})
そして、これを使用する方法は次のとおりです(すでに注入されていると仮定します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');