【问题标题】:Update Angular ngModel of a Select changed by jQuery更新由 jQuery 更改的 Select 的 Angular ngModel
【发布时间】:2023-04-02 12:19:01
【问题描述】:

我有一个 3rd 方 jQuery 应用程序,我对它的控制很少,我不能也不想使用其他任何东西,所以请不要告诉我我不应该这样做......所以这个应用程序使将<select> 更改为空值(我可以控制),我希望让我的 AngularJS ngModel 知道 jQuery 将该选择更改为另一个值。
除了使用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() 的原因

【问题讨论】:

    标签: javascript jquery angularjs angularjs-scope


    【解决方案1】:

    您可以使用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));
    

    【讨论】:

    • 确实有效,它是否也以某种方式净化了价值?既然你知道eval() 使用起来不安全......
    • 是的!该字符串被编译为 Angular 表达式,它有几个限制来防止执行不安全的代码。您可以了解有关表达式here 的更多信息并获取有关$eval() 的完整详细信息here
    • 哇,非常感谢,这确实是一个很好的解决方案,在接受之前我会看看是否有其他答案出现,但到目前为止你的答案是最好的;)
    • 看着您的代码与我的代码混合在一起,我刚刚看到我实际上怀疑scope.$evalAsync() 是否有用,我应该直接使用您的scope.$eval() 代码...谢谢这个,效果很好!
    【解决方案2】:

    所以,我不确定我是否能 100% 了解你在这里所做的一切,但也许这会有所帮助.. 我假设(并希望)您将此控件包装为指令,对吗?那么,这是否就像将传递给指令的 ngModel 传递给指令(使用 2 路绑定)然后使用 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();
          }
    
        }
        }
    

    该指令有两种方式绑定到视图中的控制器,因此当您的 jquery 元素在此处设置值时,它会更改外部范围控制器中的值。

    【讨论】:

    • 谢谢,但不幸的是它是一个 3rd 方应用程序,不能真正使用指令,因为它不是 Angular 而是 jQuery...
    猜你喜欢
    • 2018-07-15
    • 2021-10-16
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 2018-12-25
    • 2016-12-30
    • 2015-01-01
    • 2020-05-18
    相关资源
    最近更新 更多