【问题标题】:Angular view doesn't update when using splice from directive使用指令中的拼接时角度视图不会更新
【发布时间】:2015-09-24 10:11:07
【问题描述】:

我正在构建一个 Angular 应用程序,您可以在其中添加和删除页面中的小部件/模块。不同类型的模块有不同的模板。 但是,当我使用拼接删除对象时,视图没有更新。 我试过打电话给 $scope.$apply();从 deleteModule 函数,但得到一个正在进行的错误。

我在由指令添加的按钮上调用ng-click="deleteModule(module)。 此外,$scope.modules.indexOf(module); 的结果始终为 -1。我想这些问题是齐头并进的。

编辑: 做了个codepenhttp://codepen.io/anon/pen/XmjEJr

控制器和指令:

var ponk = angular.module("ponk", []);

ponk.controller("AppCtrl", ["$scope", function($scope) {

  //dummy data
  $scope.modules = [
    {
      type: "text",
      content: "this is a text field"
    },
    {
      type: "youtube",
      content: "adress to youtubevideo"
    }
    ];

    $scope.showAddModule = false;

    $scope.newModule = {
      type: "text",
      content: ""
    }

  $scope.toggleAddModule = function () {
           $scope.showAddModule = !$scope.showAddModule;
  };

  $scope.addModule = function() {
      $scope.modules.push($scope.newModule);
      $scope.newModule = { type: "text", };
      $scope.showAddModule = false;
  };

  $scope.deleteModule = function(module) {
      var index = $scope.modules.indexOf(module);
      if(index != -1) {
        $scope.modules.splice(index);
        console.log("splice");
      } else {
        console.log("nosplice");
      }
      console.log($scope.modules);
  };

}]);

ponk.directive("module", function($compile) {
// the deletebutton is added here
  var before = '<div><span class="glyphicon glyphicon-remove-circle pointer" ng-click="deleteModule(module)"></span></div>';
  var textTemplate = '<div class=" col-xs-2">' + before + '<div class="module">{{ module.content }}</div></div>';
  var youtubeTemplate = '<div class="col-xs-4">' + before + '<div class="module"><iframe id="ytplayer" type="text/html" width="500" height="300" src="http://www.youtube.com/embed/?autoplay=0" frameborder="0"/></div></div>';

  var getTemplate = function(type) {

    var template = "";
    switch(type) {
      case "youtube":
        template = youtubeTemplate;
        break;
      case "text":
      default:
        template = textTemplate;
        break;
    }
    return template;
  }

  var linker = function(scope, element, attrs) {
    var el = $compile(getTemplate(scope.module.type))(scope);
    element.replaceWith(el);
  }

  return {
    scope: {module: '=',},
    transclude: 'true',
    controller: 'AppCtrl',
    restrict: 'E',
    link: linker,
  }
});

HTML:

<div class="container-fluid" ng-app="ponk" ng-controller="AppCtrl">

    <div class="row">
      <div class="col-xs-2">

          <button class="btn btn-default add-module" ng-click="toggleAddModule()">Add module</button>
          <div ng-show="showAddModule">
            <form action="" novalidate>
              <div class="form-group">
                <label for="moduleType"></label>
                <select class="form-control" name="moduleType" ng-model="newModule.type">
                  <option value="text" selected>Text</option>
                  <option value="youtube">Youtube</option>
                </select>
              </div>

              <div ng-switch="newModule.type">

                <div ng-switch-when="youtube" class="form-group">
                  <label for="youtube">Youtube</label>
                  <input type="text" name="youtube" ng-model="newModule.content" class="form-control">
                </div>
                <div ng-switch-when="text" class="form-group">
                  <label for="formText">Text</label>
                  <textarea ng-model="newModule.content" name="formText" class="form-control"></textarea>
                </div>

              </div>
              <button ng-click="addModule()" type="button" class="btn btn-default">Add</button>
            </form>
          </div>
      </div>
      
      <div class="col-xs-10">
        <!-- the directive -->
        <module ng-repeat="module in modules" module="module"></module>
      </div>
      
    </div>

【问题讨论】:

  • 正确的调用是 myArray.splice(index, 1) 从索引开始拼接 1 个元素。
  • 现在猜一猜:您的指令正在使用隔离作用域,并且无法访问父作用域上定义的 deleteModule 函数。测试:在你的函数中添加console.log('hello');,并检查按下按钮时是否打印。 (除了上面对split的错误使用的评论)。
  • 函数运行,所以这不是问题。

标签: javascript angularjs angularjs-directive angularjs-scope


【解决方案1】:

您需要指定要删除的元素数量,在您的情况下:$scope.modules.splice(index,1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 2019-01-19
    相关资源
    最近更新 更多