AngularJS: মডেল অ্যারে থেকে কোনও মডেল উপাদান ছড়িয়ে দেওয়া হলে এনজি-রিপিট তালিকা আপডেট হয় না


100

আমার কাছে দুটি কন্ট্রোলার রয়েছে এবং একটি অ্যাপ্লিকেশন কারখানার সাথে তাদের মধ্যে ডেটা ভাগ করি।

কোনও লিঙ্ক ক্লিক করা হলে প্রথম নিয়ামক মডেল অ্যারেতে একটি উইজেট যুক্ত করে (প্লাগিনস ডিসপ্লেড)। উইজেটটি অ্যারেতে ঠেলাঠেলি করা হয় এবং এই পরিবর্তনটি ভিউতে প্রতিফলিত হয় (যা অ্যারের সামগ্রীটি দেখানোর জন্য এনজি-রিপিট ব্যবহার করে):

<div ng-repeat="pluginD in pluginsDisplayed">
    <div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"></div>
</div>

উইজেটটি কে-প্লাগইন, সরান এবং পুনরায় আকার দেওয়ার জন্য তিনটি নির্দেশে নির্মিত built সরানোর নির্দেশটি কে 2 প্লাগইন নির্দেশের টেম্পলেটটিতে একটি স্প্যান যুক্ত করে। স্প্যানটি ক্লিক করার সময়, ভাগ করা অ্যারেতে সঠিক উপাদানটি মুছে ফেলা হয় 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);
        })
    };
});

উত্তর:


131

আপনি যখনই অ্যাঙ্গুলারজেএসের বাইরে কোনও রূপ অপারেশন করেন, যেমন jQuery এর সাথে একটি অ্যাজাক্স কল করা বা আপনার মতো উপাদানগুলিতে কোনও ইভেন্টকে বাঁধাই করার দরকার থাকে তখন আপনাকে এঙ্গুলারজেএসকে নিজে আপডেট করতে দেওয়া উচিত। আপনার কোডগুলি পরিবর্তন করতে হবে তা এখানে:

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


4
Moving প্রয়োগের জন্য পাস করা একটি এক্সপ্রেশন / ফাংশনের ভিতরে স্কোপ.রিমোভ (উপাদান) এবং স্কোপ.সেসেজ (এলিমেন্ট) সরানোর বিষয়ে বিবেচনা করুন।
পার হর্নশেজ-শিয়েরবেক

1
@ পেরহর্নশেজ-শিয়েবেক আমি সম্মত, অন্যথায় কৌণিক ত্রুটিগুলি সম্পর্কে সচেতন হবে না।
জিম আহো

2
সতর্ক হোন ! সাধারণত, কৌনিকটি ডাইজেস্ট চক্রকে কল করে যখন তাকে করতে হবে এবং $ প্রয়োগ করে ম্যানুয়ালি কল করবে। এটিকে ম্যানুয়ালি কল করা প্রায়শই খারাপ অভ্যাস, কারণ আমরা অপ্টিমাইজেশনের ত্রুটি করতে পারি, এবং এটি সম্পদ গ্রহণযোগ্য হতে পারে।
অ্যালেক্স

আমি বুঝতে পারি না যে এটি আপনি কী রেখেছেন তা মুছে ফেলুন বা পুনরায় আকার দিন।
দেশার্লো দেসাফিও গেরেরো

53

আপনি যদি $scope.$apply();পরে কোনও ডান যুক্ত করেন $scope.pluginsDisplayed.splice(index,1);তবে এটি কার্যকর হয়।

কেন এটি হচ্ছে তা সম্পর্কে আমি নিশ্চিত নই, তবে মূলত যখন AngularJS জানে না যে। সুযোগটি পরিবর্তিত হয়েছে, তখন তাকে কল করতে হবে man ম্যানুয়ালি প্রয়োগ। আমি AngularJS এও নতুন তাই এটিকে আরও ভাল করে ব্যাখ্যা করতে পারি না। আমার এটি আরও সন্ধান করা প্রয়োজন।

আমি এই দারুণ নিবন্ধটি পেয়েছি যা এটি বেশ সঠিকভাবে ব্যাখ্যা করে। দ্রষ্টব্য: আমি মনে করি "মোডাউনডাউন" বাঁধার পরিবর্তে এনজি-ক্লিক (ডক্স) ব্যবহার করা ভাল । আমি AngularJS এর ​​উপর ভিত্তি করে এখানে একটি সাধারণ অ্যাপ ( http://avinash.me/losh , উত্স http://github.com/hardfire/losh ) লিখেছি । এটি খুব পরিষ্কার নয়, তবে এটি সহায়ক হতে পারে।


7

আমারো একই ইস্যু ছিল. সমস্যাটি হ'ল কারণ 'এনজি-কন্ট্রোলার' দু'বার সংজ্ঞায়িত হয়েছিল (রাউটিং এবং এইচটিএমএলেও)।



0

এটি করার একটি সহজ উপায় আছে। খুব সহজ. যেহেতু আমি এটি লক্ষ্য করেছি

$scope.yourModel = [];

আপনি এটি করতে পারেন এমন সমস্ত $ সুযোগ.আপনার মডেল অ্যারে তালিকাটি সরিয়ে দেয়

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

ক্লোনডঅবজেক্টস দিয়ে $ সুযোগ.আপনার মডেল আপডেট করা হবে।

আশা করি এইটি কাজ করবে.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.