【问题标题】:angular change property of scope by reference from ng-init通过 ng-init 引用范围的角度更改属性
【发布时间】:2014-09-15 05:14:04
【问题描述】:

我有一个输入和一个按钮,我希望当按钮被点击时,输入的值会改变:

<input type="text" ng-model='myModel'>
<button ng-click="changeMyModel()">my button</button>

在控制器中:

$scope.changeMyModel = function () {
   $scope.myModel = 'new value';
}

它可以工作,但是当我想将 myModel 传递给 changeMyModel() 函数时:

<input type="text" ng-model='myModel'>
<button ng-click="changeMyModel(myModel)">my button</button>

$scope.changeMyModel = function (myModel) {
   myModel = 'new value';
}

没有用

我真的想将一个属性传递给一个函数,因为当我使用 ng-repeat 时,每个循环,模型都是不同的,并且我不能在循环时为数组的 n 个元素声明 n var(我有 $sope .objects):

    <div ng-repeat="object in objects">
            <input type="text" ng-model='object'>
            <button ng-click="changeMyModel(object )">my button</button>
    </div>

【问题讨论】:

  • 在 JS 中字符串是不可变的,这有一些副作用,其中它们有点像原语而不是对象,您的 myModel 属性应该是对象而不是字符串。如果它是一个具有属性的对象,并且您将该对象传递给函数,那么更改该模型的属性将是有效的。此外,ng-init 有一个非常特殊的用例(对于 ng-repeat 对 $index 或其他特殊属性的引用),文档声明它不应该在其他上下文中使用,而是在控制器中初始化。
  • @shaunhusain 即使我传递了一个对象,它也不起作用,即使我传递了数组的键,它也不起作用
  • @shaunhusain 给出的建议是正确的。确保您的模型更改函数将实际对象作为参数,但通过其属性修改对象的值。这里的粗略示例 - jsfiddle.net/zgybdxjb
  • 请参阅youtu.be/ZhfUv0spHCY?t=32m,了解有关此错误的原因和简单规则的更多详细信息。 controllerAs 语法稍微改变了这条规则,但如果你使用的是原始样式,那么这适用。下面的答案应该是好的,如果不是,请显示一个解决问题的问题。

标签: angularjs angularjs-directive angularjs-ng-repeat


【解决方案1】:

在 ng-repeat 中,可以修改对象,你可以这样做:

<div class="test" ng-controller="Ctrl">
  <div ng-repeat="task in tasks">
   <button ng-click="removeTask(task);">{{task.name}}</button>
  </div>
<div>

在控制器中:

var app = angular.module('app', []);

function Ctrl($scope) {
  $scope.tasks = [{id:1,'name':'test1'}, {id:2,'name':'test2'}, {id:3,'name':'test3'}];

  $scope.removeTask = function(task){
        task.name = 'abc';
  };
}

或者您可以将列表中的项目索引传递给您的函数

【讨论】:

    【解决方案2】:

    不能通过添加一些修饰符来将 an 的字符串属性视为对象,这真的很不酷。

    你想做的。

    $scope.user = "name";
    
    $scope.setthisscopevariable = function(scopevariable) {
        scopevariable = "newname";
    }
    $scope.setthisscopevariable($scope.user);
    

    但这只是评估为 var scopevariable = "newname" 因为它传入字符串而不是对范围的引用。如果不将 $scope.user 更改为具有您要设置的属性的对象,则无法将其作为引用传递。

    所以你可以这样做

    $scope.user = "name";
    $scope.setthisscopevariable = function(scopevariable) {
        /* not doing anything with scopevariable by you could */ 
        return "newname";
    }
    $scope.user = $scope.setthisscopevariable($scope.user);
    

    在你的控制器中使用一个不知道对象的函数来设置一个值是很好的。

    当绑定到模型时,它可能看起来像这样。

    <input type="text" ng-model='myModel'>
    <button ng-click="changeMyModel('myModel')">my button</button>
    
    $scope.changeMyModel(modelName) {
        $scope[modelName] = "newname";        
    };
    

    我没有对此进行测试,但我认为它应该可以工作。它允许您将 $scope.myModel 引用作为字符串传递,这样您就可以使用数组语法在 $scope 中访问该模型。这不像您想要的那样干净,因为您的函数仍然必须处理存在一个对象和另一个答案中的子对象的事实,但它允许您将子对象作为字符串传递而不是创建爬行孩子们。如果你想更进一步,让函数存在于控制器之外的库中,你仍然需要考虑到你需要传入一个对象。

    <input type="text" ng-model='myModel'>
    <button ng-click="changeMyModel('myModel')">my button</button>
    
    $scope.changeMyModel(modelName) {
        changeText($scope, modelName);    
    };
    
    var changeText = function(obj, property) {
        obj[property] = "newname"; 
    }
    

    我无法用抽象的编码术语回答这个问题,所以我想我只是尝试一个外行的例子。 :)

    【讨论】:

      【解决方案3】:

      如@shaunhusain 所述,您应该将变量定义为对象,

      我做了一个例子for you

       function($scope){
             $scope.user = {};
              $scope.user.name = 'test'
             $scope.changeMyModel = function (myModel) {
                myModel.name = 'new value';
             }
          })
      

      也推荐给read

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-27
        • 2017-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-13
        • 1970-01-01
        相关资源
        最近更新 更多