AngularJS: 모델 요소가 모델 배열에서 스플라이스된 경우 ng-repeat 목록이 업데이트되지 않음
저는 2개의 컨트롤러를 가지고 있으며 app.factory 기능으로 데이터를 공유합니다.
첫 번째 컨트롤러는 링크를 클릭하면 모델 어레이(pluginsDisplayed)에 위젯을 추가합니다.위젯이 어레이에 푸시되고 이 변경 내용이 보기에 반영됩니다(ng-repeat을 사용하여 어레이 내용을 표시).
<div ng-repeat="pluginD in pluginsDisplayed">
<div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"></div>
</div>
위젯은 k2플러그인, 제거 및 크기 조정의 세 가지 지침을 기반으로 구축됩니다.remove 디렉티브는 k2plugin 디렉티브의 템플릿에 스팬을 추가합니다.해당 스팬을 클릭하면 공유 어레이의 오른쪽 요소가 삭제됩니다.Array.splice()공유 어레이가 올바르게 업데이트되었지만 변경 내용이 보기에 반영되지 않습니다.그러나 다른 요소가 추가되면 제거 후 보기가 올바르게 새로 고쳐지고 이전에 삭제된 요소가 표시되지 않습니다.
내가 뭘 잘못 알고 있는 거지?왜 이게 안 되는지 설명해 주시겠어요?AngularJS를 사용하는 더 좋은 방법이 있을까요?
이것은 내 인덱스입니다.html:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js">
</script>
<script src="main.js"></script>
</head>
<body>
<div ng-app="livePlugins">
<div ng-controller="pluginlistctrl">
<span>Add one of {{pluginList.length}} plugins</span>
<li ng-repeat="plugin in pluginList">
<span><a href="" ng-click="add()">{{plugin.name}}</a></span>
</li>
</div>
<div ng-controller="k2ctrl">
<div ng-repeat="pluginD in pluginsDisplayed">
<div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"></div>
</div>
</div>
</div>
</body>
</html>
이게 제 메인입니다.
var app = angular.module ("livePlugins",[]);
app.factory('Data', function () {
return {pluginsDisplayed: []};
});
app.controller ("pluginlistctrl", function ($scope, Data) {
$scope.pluginList = [{name: "plugin1"}, {name:"plugin2"}, {name:"plugin3"}];
$scope.add = function () {
console.log ("Called add on", this.plugin.name, this.pluginList);
var newPlugin = {};
newPlugin.id = this.plugin.name + '_' + (new Date()).getTime();
newPlugin.name = this.plugin.name;
Data.pluginsDisplayed.push (newPlugin);
}
})
app.controller ("k2ctrl", function ($scope, Data) {
$scope.pluginsDisplayed = Data.pluginsDisplayed;
$scope.remove = function (element) {
console.log ("Called remove on ", this.pluginid, element);
var len = $scope.pluginsDisplayed.length;
var index = -1;
// Find the element in the array
for (var i = 0; i < len; i += 1) {
if ($scope.pluginsDisplayed[i].id === this.pluginid) {
index = i;
break;
}
}
// Remove the element
if (index !== -1) {
console.log ("removing the element from the array, index: ", index);
$scope.pluginsDisplayed.splice(index,1);
}
}
$scope.resize = function () {
console.log ("Called resize on ", this.pluginid);
}
})
app.directive("k2plugin", function () {
return {
restrict: "A",
scope: true,
link: function (scope, elements, attrs) {
console.log ("creating plugin");
// This won't work immediately. Attribute pluginname will be undefined
// as soon as this is called.
scope.pluginname = "Loading...";
scope.pluginid = attrs.pluginid;
// Observe changes to interpolated attribute
attrs.$observe('pluginname', function(value) {
console.log('pluginname has changed value to ' + value);
scope.pluginname = attrs.pluginname;
});
// Observe changes to interpolated attribute
attrs.$observe('pluginid', function(value) {
console.log('pluginid has changed value to ' + value);
scope.pluginid = attrs.pluginid;
});
},
template: "<div>{{pluginname}} <span resize>_</span> <span remove>X</span>" +
"<div>Plugin DIV</div>" +
"</div>",
replace: true
};
});
app.directive("remove", function () {
return function (scope, element, attrs) {
element.bind ("mousedown", function () {
scope.remove(element);
})
};
});
app.directive("resize", function () {
return function (scope, element, attrs) {
element.bind ("mousedown", function () {
scope.resize(element);
})
};
});
jQuery를 사용하여 Ajax 콜을 실행하거나 여기서와 같은 요소에 이벤트를 바인딩하는 등 AngularJS 외부에서 어떤 형식의 작업을 수행할 때는 항상 Angular에서JS는 스스로 갱신할 수 있습니다.필요한 코드 변경은 다음과 같습니다.
app.directive("remove", function () {
return function (scope, element, attrs) {
element.bind ("mousedown", function () {
scope.remove(element);
scope.$apply();
})
};
});
app.directive("resize", function () {
return function (scope, element, attrs) {
element.bind ("mousedown", function () {
scope.resize(element);
scope.$apply();
})
};
});
이 매뉴얼은 https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply 입니다.
를 추가하는 경우$scope.$apply();직후에$scope.pluginsDisplayed.splice(index,1);효과가 있습니다.
왜 이런 일이 생기는지는 모르겠지만 기본적으로 Angular가JS는 $scope가 변경되었음을 알지 못하기 때문에 $apply를 수동으로 호출해야 합니다.나도 Angular는 처음이야.그래서 JS는 이것을 더 잘 설명할 수 없다.나도 좀 더 알아봐야겠어.
나는 그것을 꽤 정확하게 설명하는 이 멋진 기사를 발견했다.주의: "mouthdown"에 바인딩하는 것보다 ng-click (docs)를 사용하는 것이 더 나을 수 있습니다.여기 간단한 앱(http://avinash.me/losh, 출처: AngularJS에 기반한 http://github.com/hardfire/losh))을 작성했습니다.아주 깨끗하지는 않지만 도움이 될 수도 있어요.
저도 같은 문제가 있었어요.문제는 'ng-controller'가 두 번 정의되었기 때문입니다(라우팅 및 HTML에서도).
ng-repeat에서 "인덱스에 의한 추적"을 삭제하면 DOM이 새로 고쳐집니다.
그렇게 하는 쉬운 방법이 있어요.아주 쉬워요.눈치 챘을 때부터
$scope.yourModel = [];
$120을 모두 삭제합니다.다음과 같이 할 수 있는 모델 배열 목록
function deleteAnObjectByKey(objects, key) {
var clonedObjects = Object.assign({}, objects);
for (var x in clonedObjects)
if (clonedObjects.hasOwnProperty(x))
if (clonedObjects[x].id == key)
delete clonedObjects[x];
$scope.yourModel = clonedObjects;
}
$스코프당신의 모델은 cloneObjects로 갱신됩니다.
도움이 됐으면 좋겠다.
언급URL : https://stackoverflow.com/questions/15475601/angularjs-ng-repeat-list-is-not-updated-when-a-model-element-is-spliced-from-th
'programing' 카테고리의 다른 글
| 필드 유형을 변경하려면 어떻게 해야 합니다. (0) | 2023.02.28 |
|---|---|
| ASP에서 JSON 개체를 반환하는 중입니다.NET 페이지 (0) | 2023.02.28 |
| 내 HTML에서 WordPress 연락처 양식 7을 사용하는 방법 (0) | 2023.02.28 |
| Android에서 Post 매개 변수를 사용하여 HttpClient 및 HttpPost 사용 (0) | 2023.02.28 |
| Qt 4.7에서 JSON을 해석하는 가장 쉬운 방법 (0) | 2023.02.28 |