简体   繁体   English

AngularJS-从另一个指令创建元素后,指令链接功能不会触发

[英]AngularJS - Directive link function won't trigger after element is created from another directive

I'm making a data form and part of it requires that it have a button to add another row of questions and another button to delete it's corresponding row. 我正在制作一个数据表单,其中的一部分要求它有一个按钮来添加另一行问题,另一个按钮来删除其对应的行。 Hopefully I've just overlooked something and it's a simple fix, but if I have to reorganize any code I will. 希望我只是忽略了一些东西,这是一个简单的解决方法,但是如果我必须重新组织任何代码,我会做到的。 The problem I'm having is that when you click Add Stack it adds a new row of questions exactly like it's supposed to, but when you click Delete Stack nothing happens. 我遇到的问题是,当您单击“添加堆栈”时,它完全按照预期方式添加了新的问题行,但是当您单击“删除堆栈”时,什么也没发生。 From various methods of debugging I've found that the problem stems from the fact that the delete button is generated, and if I were to put a row that loads initially with the page it works just like it's supposed to. 从各种调试方法中,我发现问题源于生成了删除按钮的事实,如果我要放置一行最初在页面上加载的行,则该行将按预期运行。 I would also like to point out that for the purposes of debugging the delete button just prints "test" to the console instead of actually deleting a row. 我还想指出,出于调试目的,删除按钮只是将“ test”打印到控制台,而不是实际删除一行。

The relevant files are as following: 相关文件如下:

app.js app.js

/*global angular*/

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

app.config(['$routeProvider', function ($routeProvider) {
    'use strict';

    $routeProvider.when('/', {
        templateUrl: 'html/home.html'
    }).otherwise({
        redirectTo: '/'
    });

}]);

app.controller('MainController', function ($scope, $http) {
    'use strict';

    $http.get('json/data.json').then(function (response) {
        $scope.data = response.data;
    });

    $scope.change = function (item) {
        return item + '-changed';
    };
});

app.directive('removeStackButton', function() {
    return {
        link: function(scope, element) {
            scope.removeStack = function() {
                console.log("test");
            }
        }
    }
});

app.directive('addStackButton', ['$http', function($http) {
    return {
        link: function(scope, element) {
            scope.addStack = function() {
                $http.get('html/stack.html').then(function (response) {
                    var row = $compile(response.data)(scope);
                    element.parent().parent().prepend(row);
                });
            }
        }
    }
}]);


stack.html stack.html

<div class="form-group">
    <div class="form-group">
        <div class="row">
            <div class="col-xs-4">
                <label for="stacks_totes">Totes:</label>
                <select name="stacks_totes[]" class="form-control">
                    <option value="0" selected="selected">0</option>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                    <option value="4">4</option>
                    <option value="5">5</option>
                    <option value="6">6</option>
                </select>
            </div>
            <div class="col-xs-4">
                <label for="capped_stack">Cap:</label>
                <select name="capped_stack[]" class="form-control">
                    <option value="0" selected="selected">No cap</option>
                    <option value="1">Cap w/o litter</option>
                    <option value="2">Cap w/ litter</option>
                </select>
            </div>
            <div class="col-xs-4">
                <label for="cap_height">Cap height:</label>
                <select name="cap_height[]" class="form-control">
                    <option value="0" selected="selected">(No cap)</option>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                    <option value="4">4</option>
                    <option value="5">5</option>
                    <option value="6">6</option>
                </select>
            </div>
        </div>
    </div>
    <div class="form-group">
        <div class="row">
            <div class="col-xs-12">
                <button class="btn btn-danger btn-block btn-sm ng-scope" remove-stack-button ng-click="removeStack()">Delete Stack</button>
            </div>
        </div>
    </div>
    <hr/>
</div>


home.html home.html

<div>
    <form>
        <fieldset>
            <legend>Stacks</legend>
            <div class="form-group">
                <div class="form-group">
                    <button class="btn btn-block" add-stack-button ng-click="addStack()">Add Stack</button>
                </div>
            </div>
        </fieldset>
    </form>
</div>


index.html index.html

<!DOCTYPE html>
<html ng-app="app">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <link rel="stylesheet" href="vendor/bootstrap-3.3.5-dist/css/bootstrap.min.css" />
    <script type="text/javascript" src="vendor/jquery-2.1.4/jquery-2.1.4.min.js"></script>
    <script type="text/javascript" src="vendor/bootstrap-3.3.5-dist/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="vendor/angular-1.4.4/angular.min.js"></script>
    <script type="text/javascript" src="vendor/angular-1.4.4/angular-route.min.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>


<body ng-controller="MainController">

    <ng-include src="'html/navbar.html'"></ng-include>
    <ng-view></ng-view>
</body>

To address your comment of ng-repeat , you should create a model and work off that instead of the DOM. 要解决您对ng-repeat评论,您应该创建一个模型并对其进行处理,而不是DOM。 Chuck your stackForm into a directive. 将您的stackForm插入指令。 See plunker Eg: plunker例如:

app.controller('MainCtrl', function ($scope, $http) {
    // The stackList is your model. Work off this list instead.
    $scope.stackList = [];

    $scope.addStack = function() {
      $scope.stackList.push({});
    };

    $scope.removeStack = function(stack) {
      var stackIdx = $scope.stackList.indexOf(stack);
      if (stackIdx > -1) {
        $scope.stackList.splice(stackIdx, 1);
      }
    };
});

And in your markup: 在您的标记中:

  <button class="btn btn-block" ng-click="addStack()">Add Stack</button>
  ...
  <div data-ng-repeat="stack in stackList track by $index">
    <div data-stack="stack" data-remove-stack="removeStack(stack)"></div>
  </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM