Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS指令中的两个绑定_Javascript_Html_Angularjs_Data Binding_Typescript - Fatal编程技术网

Javascript AngularJS指令中的两个绑定

Javascript AngularJS指令中的两个绑定,javascript,html,angularjs,data-binding,typescript,Javascript,Html,Angularjs,Data Binding,Typescript,问题:我有一个控制器,它获取一组播放器,并将它们呈现给用户。这些玩家有一组统计数据,用户可以增加或减少,因为一个玩家可以有多个统计数据,我希望他们的行为相同,所以我创建了一个指令,有一个数字和两个按钮“+”和“-”。当用户单击“+”时,值应该上升,当用户单击“-”时,值应该下降。该指令的目标是使调整模板变得容易,并使其在所有地方都得到反映,该指令还试图做到统计不可知,这样就可以将其重新用于多个不同的统计。用户可以选择播放器,此指令将绑定到此selectedPlayer上的状态。我遇到的问题是,如

问题:我有一个控制器,它获取一组播放器,并将它们呈现给用户。这些玩家有一组统计数据,用户可以增加或减少,因为一个玩家可以有多个统计数据,我希望他们的行为相同,所以我创建了一个指令,有一个数字和两个按钮“+”和“-”。当用户单击“+”时,值应该上升,当用户单击“-”时,值应该下降。该指令的目标是使调整模板变得容易,并使其在所有地方都得到反映,该指令还试图做到统计不可知,这样就可以将其重新用于多个不同的统计。用户可以选择播放器,此指令将绑定到此selectedPlayer上的状态。我遇到的问题是,如果我更改selectedPlayer,指令似乎不会用新的selectedPlayer更新,或者指令中的新值似乎不会实际更新选定的播放器

代码可能有助于更好地解释这一点

<div class="h3 text-center">{{title}}</div>
<button class="btn btn-lg plusMinus-btn btn-danger" ng-click="statCtrlr.statDown()">-</button>
<span class="stat-val digits md vcenter text-center" style="width: 50px;" ng-cloak>{{statCtrlr.statValue}}</span>
<button class="btn btn-lg plusMinus-btn btn-success" ng-click="statCtrlr.statUp()">+</button>
如何在html中调用它

<div class="col-xs-3 no-gutter">
     <stat-val title="FGM" data="entryCtrlr.selectedPlayer.stats.fgm" prop="fgm"
     ></stat-val>
</div>
更新

控制台转储:


您的
$scope.data
是双向绑定的,而不是
ctrl.statValue

this.statDown = () => {
    console.log("statDown", $scope.data);
    if ($scope.data > 0) {
        $scope.data--;
    }
};

this.statUp = () => {
   console.log("statUp", $scope.data);
   $scope.data++;
};

您的
$scope.data
是双向绑定的,而不是
ctrl.statValue

this.statDown = () => {
    console.log("statDown", $scope.data);
    if ($scope.data > 0) {
        $scope.data--;
    }
};

this.statUp = () => {
   console.log("statUp", $scope.data);
   $scope.data++;
};

关键问题隐藏在这里:

...
ctrl.statValue = $scope.data;
...
这是一个发生在控制器构造阶段的语句。也就是说,$scope.data此时可能为空。。。因此,我们不会为以后的数据指定引用。。。仅分配(或未定义)空值:

父控制器中存在异步数据加载(超出指令)

我们怎样才能解决它?最简单的方法是在模型名称中使用“.”,使用
模型:{data}

控制器创建一个模型

.controller("myCtrl", function($scope, $http) {
  $scope.Model = {};
  $http.get("data.json")
    .then(function(response){
      $scope.Model.data = response.data;
    })
})
这被传递给指令

  .directive('statVal', function()
  {
    return {
        restrict: 'E',
        templateUrl: 'templates/statValue.html',
        //transclude:true,
        scope: {
            data: "=",
            // ...
        },
        controllerAs: 'statCtrlr',
        controller: ['$scope', '$http', function ($scope, $http) {
            //$scope.statValue
            var ctrl = this;

            //ctrl.statValue = $scope.data[$scope.prop];
            console.log("$scope", $scope);

            ctrl.statValue = $scope.data;
        }],
    };
  })

.controller("myCtrl", function($scope, $http) {
  $http.get("data.json")
    .then(function(response){
      $scope.data = response.data;
    })
})
<stat-val model="Model"></stat-val> 
检查一下

另一种方法是观察原始数据。。。直到它们真正到达指令,然后将它们分配给控制器。。。但我试图解释发生了什么,上面的例子更精确


注意:我仅使用JavaScript作为示例,因为这里的问题与Typescript无关

关键问题隐藏在这里:

...
ctrl.statValue = $scope.data;
...
这是一个发生在控制器构造阶段的语句。也就是说,$scope.data此时可能为空。。。因此,我们不会为以后的数据指定引用。。。仅分配(或未定义)空值:

父控制器中存在异步数据加载(超出指令)

我们怎样才能解决它?最简单的方法是在模型名称中使用“.”,使用
模型:{data}

控制器创建一个模型

.controller("myCtrl", function($scope, $http) {
  $scope.Model = {};
  $http.get("data.json")
    .then(function(response){
      $scope.Model.data = response.data;
    })
})
这被传递给指令

  .directive('statVal', function()
  {
    return {
        restrict: 'E',
        templateUrl: 'templates/statValue.html',
        //transclude:true,
        scope: {
            data: "=",
            // ...
        },
        controllerAs: 'statCtrlr',
        controller: ['$scope', '$http', function ($scope, $http) {
            //$scope.statValue
            var ctrl = this;

            //ctrl.statValue = $scope.data[$scope.prop];
            console.log("$scope", $scope);

            ctrl.statValue = $scope.data;
        }],
    };
  })

.controller("myCtrl", function($scope, $http) {
  $http.get("data.json")
    .then(function(response){
      $scope.data = response.data;
    })
})
<stat-val model="Model"></stat-val> 
检查一下

另一种方法是观察原始数据。。。直到它们真正到达指令,然后将它们分配给控制器。。。但我试图解释发生了什么,上面的例子更精确


注意:我仅使用JavaScript作为示例,因为这里的问题与Typescript无关,而不应该是ctrl.statValue,而是对同一事物的引用?
ctrl.statValue
只是
$scope.data
的副本,但只有scope变量是双向绑定的。因此,您必须显式地更新
$scope.data
,以便在其他地方反映更改。我的html也会像这样绑定{{$scope.data}。我是否仍然使用数据:“=”?如果您从未在.html中使用
$scope
,则.html会像这样绑定:
{{data}
。是的,您仍然应该使用
数据:“=”
是的,我让它工作了!事后看来,事情很简单,我猜就是这样。考虑到我已经让它工作了,我想使用“&”向函数传递一个ref可能更有意义,因为将来统计数据可能会以不同的方式递增,等等。但是ctrl.statValue不应该只是对同一事物的一个ref吗?
ctrl.statValue
只是
$scope.data
的一个副本,但只有作用域变量是双向绑定的。因此,您必须显式地更新
$scope.data
,以便在其他地方反映更改。我的html也会像这样绑定{{$scope.data}。我是否仍然使用数据:“=”?如果您从未在.html中使用
$scope
,则.html会像这样绑定:
{{data}
。是的,您仍然应该使用
数据:“=”
是的,我让它工作了!事后看来,事情很简单,我猜就是这样。虽然现在我已经让它工作了,但我认为使用“&”将ref传递给函数可能更有意义,因为将来统计数据可能会以不同的方式增加,等等。感谢非常好的回答,但是@avijit gupta首先回答了,它工作了。所以我将选择他的作为最终答案,再次感谢您的帮助!关键是——你有答案。太好了!享受用户界面路由器,先生;)谢谢你的回答,不过@avijit gupta先回答了,它成功了。所以我将选择他的作为最终答案,再次感谢您的帮助!关键是——你有答案。太好了!享受用户界面路由器,先生;)