更新由jQuery更改的Select的Angular ngModel

时间:2014-12-30 04:17:34

标签: javascript jquery angularjs angularjs-scope

我有一个第三方jQuery应用程序,我有最小的控制权,我不能也不想使用其他任何东西,所以请不要告诉我我不应该这样做...所以这个应用程序使<select>更改为空值(我有控制权),我希望我的AngularJS ngModel知道jQuery将select更改为另一个值。
除了使用eval()之外我似乎无法工作,我真的不想使用它,所以我尝试了各种不同的解决方案,但没有任何工作(除了eval(),正如我所说)。如果我的ngModel是一个简单的名称(名称),我的解决方案实际上会起作用,但它实际上是一个复杂的名称(object.name),所以这就是我被卡住了。

var optionObj = $('#selectId').val('');
angular.element(optionObj).triggerHandler('change');    // this fail
angular.element(optionObj).triggerHandler('onchange');  // this doesn't do anything

var scope = angular.element(optionObj).scope();
scope.$evalAsync(function(optionObj) {
    var ngModelAttr = optionObj.attr("ng-model"); // get the ng-model attribute     
    scope[ngModelAttr] = ''; // this does not work with complex object
    scope.user.language = ''; // this work, but cannot use it since ngModel naming is dynamic and unknown from within the code      

    console.debug(scope.user.language); // not empty 1st attempt, but empty on 2nd solution but is non-dynamic

    // using eval() works but it's dangerous
    eval("scope."+ngModelAttr+"=''");
}(optionObj));    

所以从那里的代码,并知道我们的Angular看起来像下面的<select ng-model="user.language">...</select>,我如何建议Angular jQuery做出改变?再次不要忘记这里我可能知道user.language的事实,但在jQuery应用程序中它不知道它,所以一切都必须动态地工作。
如果我使用eval然后它可以工作,但它不仅丑陋而且危险......

另外值得一提的是,我正在使用AngularJS 1.3,这就是我使用$evalAsync()代替$apply()的原因

2 个答案:

答案 0 :(得分:2)

您可以使用scope.$eval()将字符串计算为当前范围作为上下文的代码。使用它是安全的,因为如果字符串没有引用现有属性,它将返回undefined,并且范围是评估的上下文,因此尝试访问不在范围内的属性(如window )也将返回undefined。您可以像这样使用它:

var scope = angular.element(optionObj).scope();

scope.$evalAsync(function(optionObj) {

    var ngModelAttr = optionObj.attr("ng-model");

    scope.$eval(ngModelAttr + " = '' ");

}(optionObj));

答案 1 :(得分:0)

所以,我不确定我100%收到你在这里发生的一切,但也许这会有所帮助.. 我假设(并希望)你将这个控件包装成一个指令,对吧?那么,这只是简单地传递你的ngModel传递给指令(使用双向绑定),然后使用jQuery元素设置变量的值。

请注意这是非常粗糙的伪代码,只是为了让您了解我的意思:

在视图中:     

指令中的

angular.module('myapp.directives').directive('MyDirective',myJqueyWrappedDirective);
function myJqueryWrappedDirecive(){
  return {
    restrict: 'E',
    templateUrl: 'path/to/myTemplate.html', //you have your select element in a template
    scope: {
      myOuterNgModel: '=ngModelAttr'
     },
    link: function(scope,element){
      // #selectId is in your template
      $('#selectId').on('change', function(){ 
         scope.myOuterNgModel = $(this).val();
      }

    }
    }

该指令在视图中有2路绑定到控制器,所以当你的jquery元素在这里设置值时,它会改变外部作用域控制器中的值。