如何防止子组件更新父组件?

时间:2017-02-20 19:01:48

标签: javascript angularjs

如何防止此angularjs子组件更新其父组件?在下面的代码中,即时更新模式中的表单,它也会更新父模型。这可以防止"取消"按钮工作正常。

Here's the plunker showing the issue.

的index.html

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="//kendo.cdn.telerik.com/2017.1.118/styles/kendo.common.min.css" />
  <link rel="stylesheet" href="//kendo.cdn.telerik.com/2017.1.118/styles/kendo.bootstrap.min.css" />
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />


  <script src="//code.jquery.com/jquery-1.12.4.js"></script>
  <script src="//code.angularjs.org/1.5.8/angular.js"></script>
  <script src="//kendo.cdn.telerik.com/2017.1.118/js/kendo.all.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js"></script>

  <script id="documents-template" type="text/ng-template">
    <button id="openDetails" name="openDetails" ng-click="model.openDetails(1)" class="btn btn-default">Open Details</button>
  <pre>{{ model | json }}</pre>
  </script>

  <script id="details-template" type="text/ng-template">
    <div class="modal-body">
      <label>Name To Edit</label>
      <input ng-model="model.document.title">
      <br>
      <label>Value To Edit</label>
      <input ng-model="model.document.fileName">
      <br>
      <button class="btn btn-success" type="button" ng-click="model.save()">Save Changes</button>
      <button class="btn btn-default" type="button" ng-click="model.cancel()">Cancel</button>
    </div>
    <pre>{{ model | json }}</pre>
  </script>

  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body>

<div ng-app="app">

  <documents-component></documents-component>


</div>

</body>

</html>

的script.js

console.clear();

function documentController($uibModal, TransactionFactory) {
  var model = this;
  model.transaction = TransactionFactory;

  model.openDetails = function(id) {
    $uibModal.open({
      animation: true,
      component: 'detailsComponent',
      resolve: {
        document: function () {
          return model.transaction.documents[id - 1];
        }
      }
    }).result.then(function(result) {
      console.log("Save result was:", result);
    }, function(reason) {
      console.log("Dimissed reason was:", reason);
    });
  };
}

function detailsController() {
  var model = this;
  model.document = model.resolve.document;
  console.log("model.document", model.document);
  model.save = function() {
    console.log("saved was clicked. Passing back:", model.document);
    model.modalInstance.close(model.document);
  };
  model.cancel = function() {
    model.modalInstance.dismiss("cancel");
  };
}

var app = angular.module("app", ["kendo.directives", "ngAnimate", "ui.bootstrap"]);

app.factory('TransactionFactory', function() {

  var doc1 = { id:1, title: "Doc1", fileName: "Doc1.pdf" }
  var doc2 = { id:2, title: "Doc2", fileName: "Doc2.pdf" }
  var doc3 = { id:3, title: "Doc3", fileName: "Doc3.pdf" }
  var doc4 = { id:4, title: "Doc4", fileName: "Doc4.pdf" }
  var dummyData = [doc1, doc2, doc3, doc4];

  console.log("dummyData:", dummyData);

  return {
    documents: dummyData
  };
});

app.component("documentsComponent", {
    template: $("#documents-template").html(),
    controllerAs: "model",
    controller: ["$uibModal", "TransactionFactory", documentController]
});

app.component("detailsComponent", {
    template: $("#details-template").html(),
    bindings: {
      modalInstance: "<",
      resolve: '<'
    },
    controllerAs: "model",
    controller: [detailsController]
});

3 个答案:

答案 0 :(得分:1)

问题在于,在两个组件中,您都在使用对数据的同一对象的引用。因此,当您在模态中编辑数据时,您实际上使用父组件也使用的数据编辑原始对象。解决方案是将对象的副本传递给您的模态。

答案 1 :(得分:1)

尝试了一些更改...基本上传递所需对象的副本,并且仅在单击“保存更改”按钮时保存(分配)它。

你的功能应该是:

model.openDetails = function(id) {
$uibModal.open({
  animation: true,
  component: 'detailsComponent',
  resolve: {
    document: function () {
      return angular.copy( model.transaction.documents[id - 1] );
    }
  }
}).result.then(function(result) {
  console.log("Save result was:", result);
  model.transaction.documents[id - 1] = result ;

}, function(reason) {
  console.log("Dimissed reason was:", reason);
});

Try it out

答案 2 :(得分:1)

请参阅更新的plunker https://plnkr.co/edit/cvR8i883Q1ZlPPTA8Ryk?p=preview。你需要传递一份对象。

function detailsController() {
    var model = this;
    model.document = angular.copy(model.resolve.document);
    console.log("model.document", model.document);
    model.save = function() {
        console.log("saved was clicked. Passing back:", model.document);
        model.modalInstance.close(model.document);
    };
    model.cancel = function() {
        model.modalInstance.dismiss("cancel");
    };
}