Javascript 是否有处理“问题”的模式;取消“;在AngularJS模态对话框中?

Javascript 是否有处理“问题”的模式;取消“;在AngularJS模态对话框中?,javascript,angularjs,Javascript,Angularjs,注意:这不是关于显示AngularJS的模态对话框,这个主题有很多问题和答案 这个问题是关于如何在页面的模式对话框中对OK和Cancel做出反应。假设您有一个范围,其中只有一个变量: $scope.description = "Oh, how I love porcupines..." 如果我在页面上为您提供一个模式对话框,并在该对话框中使用ng model=“description”,那么您所做的所有更改实际上都是在您键入时对描述本身进行实时更改的。这很糟糕,因为那你怎么取消这个对话呢 有一

注意:这不是关于显示AngularJS的模态对话框,这个主题有很多问题和答案

这个问题是关于如何在页面的模式对话框中对OK和Cancel做出反应。假设您有一个范围,其中只有一个变量:

$scope.description = "Oh, how I love porcupines..."
如果我在页面上为您提供一个模式对话框,并在该对话框中使用ng model=“description”,那么您所做的所有更改实际上都是在您键入时对描述本身进行实时更改的。这很糟糕,因为那你怎么取消这个对话呢

有一个问题,就是要做我下面解释的事情。对此公认的答案与我提出的“解决方案”相同:

我可以看到,如果单击按钮调出一个模式,返回到后面的函数,为该模式创建相关数据的临时副本,然后弹出该模式,该如何操作。然后“确定”(或“保存”或其他)可以将临时值复制到实际模型值

main.js(节选):

main.html(摘录):

main.html:

<form>
  <input type="text" ng-model-uncommitted="filename"/>
  <input type="text" ng-model-uncommitted="description"/>

  <button ng-commit ng-click="persist()">Save</button>
  <button ng-discard>Cancel</button>
</form>

拯救
取消
我在它周围贴了一个表单标签,因为我不知道如何对项目进行分组,所以很明显,它是同一个“事务”的一部分(因为没有更好的词)。但是需要有一种方法可以自动实现,模型变量的克隆副本用于初始值,用于输入并自动更新、验证等,然后最终丢弃或复制到最初用于创建它们的相同值(如果用户决定提交)


在一个大的网站上,这样的事情难道不比控制器中的代码更容易在20个模态中一次又一次地完成吗?还是我疯了?

你似乎想得太多了。没有插件,因为过程非常简单。如果需要模型的原始副本,请制作一个副本并将其保存在控制器中。如果用户取消,请将模型重置为您的副本,并使用FormController。$setPristine()方法使表单再次保持原始状态

//Controller:

myService.findOne({$route.current.params['id']}, function(results) {
    $scope.myModel = results;
    var backup = results;
}

//cancel
$scope.cancel = function() {
    $scope.myModel = backup;
    $scope.myForm.$setPristine();
}
那么在你看来,

<form name="myForm">


您需要为表单命名以创建$scope.myForm控制器。

基本上,如果某个内容不是声明性的,您将生成一个指令

 .directive('shadow', function() {
  return {
    scope: {
      target: '=shadow'            
    },
    link: function(scope, el, att) {
      scope[att.shadow] = angular.copy(scope.target);

      scope.commit = function() {
        scope.target = scope[att.shadow];
      };
    }
  };
然后:

例如:


请注意,使用
$parent
时出现的问题,如果最终在中间有另一个范围,它可能会中断。

< P>面对同样的问题,并通过这个线程,我想出了<代码>懒惰模型指令,它的工作方式与<代码> NG模式完全相同,但是在提交表单>时,保存的更改仅为“强”。
 .directive('shadow', function() {
  return {
    scope: {
      target: '=shadow'            
    },
    link: function(scope, el, att) {
      scope[att.shadow] = angular.copy(scope.target);

      scope.commit = function() {
        scope.target = scope[att.shadow];
      };
    }
  };
用法:

<input type="text" lazy-model="user.name">

我尝试着保持它的简单性,使它具有声明性,而不依赖于表单标签或其他东西

一个简单的指令:

.directive("myDirective", function(){
return {
  scope: {
    item: "=myDirective"
  },
  link: function($scope){
    $scope.stateEnum = {
      view: 0, 
      edit: 1
    };

    $scope.state = $scope.stateEnum.view;

    $scope.edit = function(){
      $scope.tmp1 = $scope.item.text;
      $scope.tmp2 = $scope.item.description;
      $scope.state = $scope.stateEnum.edit;
    };

    $scope.save = function(){
      $scope.item.text = $scope.tmp1;
      $scope.item.description = $scope.tmp2;
      $scope.state = $scope.stateEnum.view;
    };

    $scope.cancel = function(){
      $scope.state = $scope.stateEnum.view;
    };
  },
  templateUrl: "viewTemplate.html"
};
})
viewTemplate.html:

<div>
  <span ng-show="state == stateEnum.view" ng-click="edit()">{{item.text}}, {{item.description}}</span>
  <div ng-show="state == stateEnum.edit"><input ng-model="tmp1" type="text"/> <input ng-model="tmp2" type="text"/><a href="javascript:void(0)" ng-click="save()">save</a> <a href="javascript:void(0)" ng-click="cancel()">cancel</a></div>
</div>

{{item.text},{{item.description}
然后设置上下文(项目):



查看它的作用:

从Angular 1.3开始,有一个指令允许在本地实现相同的行为

<form name="userForm">
    <input type="text" ng-model="user.name" ng-model-options="{ updateOn: 'submit' }" name="userName">
    <button type="submit">save</button>
    <button type="button"  ng-click="userForm.userName.$rollbackViewValue();">cancel</button>
</form>

拯救
取消

jsFIDLE:

另一种方法是在编辑模型之前复制模型,然后在取消时恢复原始模型。角度控制器代码:

//编辑时,复制原始模型并将其存储在范围中
功能编辑(模型){
//将模型置于cancel方法要访问的范围内
$scope.modelBeingEdited=模型;
//从模型->范围.originalModel复制
复制(模型,$scope.originalModel);
}
函数cancelEdit(){
//从scope.original复制回您的模型
复制($scope.originalModel,$scope.modelBeingEdited)

}
这正是我说的我不想做的,因为它与声明性解决方案相反。这是我们目前必须做的事情,但它让控制器面对HTML/UI,而不是简单地充当业务逻辑和模型客户端副本的保管人。我不遵循您的“控制器面对面”部分。副本保留在控制器中。它不接触视图,只是重置模型,与首先设置模型没有什么不同。您是否会在每个ng模型字段上设想一个指令?或者你认为Angular可以自己保存模型的阴影副本?第二种方法听起来很有趣。好吧,看看我添加的示例,看看这是否更有意义。
$setPristine()
的价值/用途是什么?这有什么帮助?您知道是否有办法使用Angular 1.3.0中的新方法
$rollbackViewValue()
,以避免存储副本?您是否正在寻找一个“取消”按钮,该按钮可自动恢复对模型所做的更改?单击“取消”按钮时刷新模型如何,这样模型将被覆盖,而不需要额外的临时变量?你能提供一个你正在寻找的语法/标记的例子吗?你不能不允许发生更改,因为用户可能会在页面上看到{{description}的实例在键入时进行更新(或者在数字的情况下重新计算值,等等)。我将补充以上内容,为我想看到的内容提供一些想法。我只是希望有些东西已经存在。你绝对不是疯子。我不清楚描述和描述。它们是两种不同的型号,而不是您的备份版本吗?在您的示例中,这些字段会显示什么?编辑或未编辑的数据?再仔细考虑一下,我很确定你可以在指令中完成你想要的。我试图让它更清楚,这些值是不相关的,我只是想表明,即使存在多个模型值,这也应该有效。我希望您打开页面,看到输入中填充了文件名和描述的当前值。编辑后
<input type="text" lazy-model="user.name">
app.directive('lazyModel', function($parse, $compile) {
  return {
    restrict: 'A',  
    require: '^form',
    scope: true,
    compile: function compile(elem, attr) {
        // getter and setter for original model
        var ngModelGet = $parse(attr.lazyModel);
        var ngModelSet = ngModelGet.assign;  
        // set ng-model to buffer in isolate scope
        elem.attr('ng-model', 'buffer');
        // remove lazy-model attribute to exclude recursion
        elem.removeAttr("lazy-model");
        return function postLink(scope, elem, attr) {
          // initialize buffer value as copy of original model 
          scope.buffer = ngModelGet(scope.$parent);
          // compile element with ng-model directive poining to buffer value   
          $compile(elem)(scope);
          // bind form submit to write back final value from buffer
          var form = elem.parent();
          while(form[0].tagName !== 'FORM') {
            form = form.parent();
          }
          form.bind('submit', function() {
            scope.$apply(function() {
                ngModelSet(scope.$parent, scope.buffer);
            });
         });
         form.bind('reset', function(e) {
            e.preventDefault();
            scope.$apply(function() {
                scope.buffer = ngModelGet(scope.$parent);
            });
         });
        };  
     }
  };
});
.directive("myDirective", function(){
return {
  scope: {
    item: "=myDirective"
  },
  link: function($scope){
    $scope.stateEnum = {
      view: 0, 
      edit: 1
    };

    $scope.state = $scope.stateEnum.view;

    $scope.edit = function(){
      $scope.tmp1 = $scope.item.text;
      $scope.tmp2 = $scope.item.description;
      $scope.state = $scope.stateEnum.edit;
    };

    $scope.save = function(){
      $scope.item.text = $scope.tmp1;
      $scope.item.description = $scope.tmp2;
      $scope.state = $scope.stateEnum.view;
    };

    $scope.cancel = function(){
      $scope.state = $scope.stateEnum.view;
    };
  },
  templateUrl: "viewTemplate.html"
};
})
<div>
  <span ng-show="state == stateEnum.view" ng-click="edit()">{{item.text}}, {{item.description}}</span>
  <div ng-show="state == stateEnum.edit"><input ng-model="tmp1" type="text"/> <input ng-model="tmp2" type="text"/><a href="javascript:void(0)" ng-click="save()">save</a> <a href="javascript:void(0)" ng-click="cancel()">cancel</a></div>
</div>
<div ng-repeat="item in myItems">
  <div my-directive="item"></div>
</div>
<form name="userForm">
    <input type="text" ng-model="user.name" ng-model-options="{ updateOn: 'submit' }" name="userName">
    <button type="submit">save</button>
    <button type="button"  ng-click="userForm.userName.$rollbackViewValue();">cancel</button>
</form>