【问题标题】:How to prevent child component from updating parent component?如何防止子组件更新父组件?
【发布时间】:2017-07-10 04:39:16
【问题描述】:

如何防止这个 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]
});

【问题讨论】:

    标签: javascript angularjs


    【解决方案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

    【讨论】:

    • 我似乎不需要额外的}).resolve: {} 代码——这对于任何特定的事情都是必要的吗?
    • 我的错误,我将其粘贴在部分中,并且错误地做了两次解析。已编辑。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      请参阅更新的 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");
          };
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-30
        • 2019-12-18
        • 1970-01-01
        • 1970-01-01
        • 2021-07-04
        • 2021-06-11
        • 2018-04-18
        • 1970-01-01
        相关资源
        最近更新 更多