source

Angular에서 "취소"를 처리하는 패턴이 있습니까?JS 모달 대화 상자?

ittop 2023. 3. 8. 21:50
반응형

Angular에서 "취소"를 처리하는 패턴이 있습니까?JS 모달 대화 상자?

참고: 이것은 AngularJS와의 모달 대화 상자를 보여주는 것이 아닙니다. 이 토픽에는 질문과 답변이 많이 있습니다.

이 질문은 페이지의 모달 대화 상자 내에서 OK와 Cancel 모두에 대응하는 방법에 대한 것입니다.변수가 1개밖에 없는 스코프가 있다고 합시다.

$scope.description = "Oh, how I love porcupines..."

페이지에 모달 대화 상자를 제공하고 해당 대화 상자에 ng-model="description"을 사용하면 실제로 사용자가 입력하는 대로 모든 변경 사항이 설명 자체에 실시간으로 적용됩니다.안됐네요, 그럼 어떻게 그 대화 상자를 취소하죠?

제가 아래에 설명하는 대로 하라는 질문이 있어요.이에 대해 받아들여진 대답은 내가 생각해낸 것과 같은 "솔루션"이다: 각진JS: 데이터 바인딩 모달 - "저장"을 클릭했을 때만 변경 내용을 저장하거나 "취소"를 클릭했을 때 변경 내용을 잊어버립니다.

모달 부팅 버튼을 클릭하면 모달 관련 데이터의 임시 복사본이 생성되고 모달 부팅이 되면 어떻게 해야 하는지 알 수 있습니다.그런 다음 "확인"(또는 "저장" 또는 기타)을 통해 임시 값을 실제 모델 값으로 복사할 수 있습니다.

main.disput(삭제):

$scope.descriptionUncommitted = $scope.description;

$scope.commitChanges = function () {
  $scope.description = $scope.descriptionUncommitted;
}

main.disput(삭제):

<input type="text" ng-model="descriptionUncommitted"/>

<button ng-click="commitChanges()">Save</button>

문제는 그게 선언적이지 않다는 거야!사실 Angular와는 전혀 다르다.JS는 어디에도 없어요.마치 ng-model-uncommitted="description"이 필요한 것 같습니다.이 경우 원하는 모든 변경을 할 수 있지만 다른 선언으로 트리거할 때만 커밋됩니다.플러그인에 그런 게 있나요, 아니면 Angular가 있나요?JS가 직접 추가할까요?

편집: 다른 방법의 예가 적절한 것 같습니다.

main.filename:

$scope.filename = "panorama.jpg";
$scope.description = "A panorama of the mountains.";

$scope.persist = function () { // Some function to hit a back end service. };

main.filename:

<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개의 모달에 대해 컨트롤러에 있는 코드보다 이런 작업을 반복하는 것이 더 쉽지 않을까요?아니면 내가 미쳤나?

기본적으로, 만약 어떤 것이 선언적이지 않다면, 당신은 지시를 내립니다.

 .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];
      };
    }
  };

그 후, 다음과 같이 입력합니다.

  <div shadow="data">
    <input ng-model="data">
    <button ng-click="commit()">save</button>
  </div>

★★★★★★★★★★★★★★★★★.data내 the의 shadow디렉티브는 원본의 복사본이 됩니다.data이치노

다음으로 작업 예를 제시하겠습니다.jsbin

이 예 이외에는 테스트해 본 적이 없기 때문에, 다른 경우는 효과가 없을지도 모르지만, 가능성이 있다고 생각합니다.

편집:

가 있는 항목)angular.copy여기서 필수): jsbin

편집 2, 각도 버전 1.2.x

변경에 따라input디렉티브 내의 는, 격리된 스코프에 액세스 할 수 없게 되었습니다.비절연자 스코프)를 입니다.scope:true데이터 복사본을 보관하고 저장하기 위해 상위 범위에 액세스합니다.

따라서 이후 버전의 angular에서는 이전과 같은 방법으로 약간 수정하여 트릭을 수행합니다.

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

      scope.commit = function() {
        scope.$parent[att.shadow] = angular.copy(scope[att.shadow]);
      };
    }
  };
});

예: jsbin

「 」의는,$parent중간에 다른 스코프가 있는 경우, 파손될 가능성이 있습니다.

Angular 1.3에서는 ngModelOptions 디렉티브가 있어 동일한 동작을 네이티브로 실행할 수 있습니다.

<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>

JSFiddle:http://jsfiddle.net/8btk5/104/

하여 이 해 낸 은, 「」입니다.lazy-model「」와 .ng-model그러나 양식을 제출한 경우에만 변경 내용을 저장합니다.

사용방법:

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

★★★★★★★★★★★★★★로 포장해 주세요.<form>태그하지 않으면 지연 모델이 원래 모델에 변경을 푸시할 시기를 알 수 없습니다.

풀워킹 데모: http://jsfiddle.net/8btk5/3/

laze Model " " " :
(github에서 실제 버전을 사용하는 것이 좋습니다.)

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);
            });
         });
        };  
     }
  };
});

GitHub의 실제 소스 코드

당신은 이것에 대해 너무 생각하는 것 같아요.프로세스가 매우 간단하기 때문에 플러그인은 없습니다.모델을 그대로 복사하려면 모델을 만들어 컨트롤러에 보관하십시오.사용자가 취소한 경우 모델을 복사본으로 재설정하고 FormController를 사용합니다.$setPristin() 메서드를 사용하여 폼을 원래대로 되돌립니다.

//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 컨트롤러를 작성하려면 폼 이름을 지정해야 합니다.

다른 방법은 모델을 편집하기 전에 복사하고 취소 시 원본을 복원하는 것입니다.각도 컨트롤러 코드:

//on edit, make a copy of the original model and store it on scope
function edit(model){
  //put model on scope for the cancel method to access
  $scope.modelBeingEdited = model;
  //copy from model -> scope.originalModel
  angular.copy(model,$scope.originalModel);  
}

function cancelEdit(){
  //copy from scope.original back to your model 
  angular.copy($scope.originalModel, $scope.modelBeingEdited)  
}
So on open of the modal dialog, call the edit function and pass a pointer to the model you want to edit. Then make sure your modal dialog is bound to $scope.editingModel. On cancel, call the cancel function, and it will copy the original values back.

그게 도움이 됐으면 좋겠네요!

단순함을 유지하고, 선언적으로 표현하며, 양식 태그나 다른 것에 의존하지 않도록 하는 시도를 해보겠습니다.

간단한 지시:

.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>

다음으로 컨텍스트(항목)를 설정합니다.

<div ng-repeat="item in myItems">
  <div my-directive="item"></div>
</div>

실제 상황 보기: http://plnkr.co/edit/VqoKQoIyhtYnge2hzrFk?p=preview

언급URL : https://stackoverflow.com/questions/16838148/is-there-a-pattern-for-dealing-with-cancel-in-angularjs-modal-dialogs

반응형