2016-12-13 11 views
10

किसी सरणी sourceArray को देखते हुए मैं एक targetArray कि पहले एक की प्रविष्टियों पर निर्भर करता है बनाने के लिए चाहते हैं के बीच Databinding। इसका मतलब है कि बनाए गए ऐरे में प्रत्येक स्रोत-प्रविष्टियों के लिए एक प्रविष्टि होनी चाहिए और जब भी sourceArray परिवर्तनों को अद्यतन किया जाता है। हालांकि targetArray को संशोधित करने से स्रोत को कभी अपडेट नहीं करना चाहिए।AngularJS: Arrays

यह PlunkersourceArray तक की तरह काम करता है स्थिर है। जैसे ही आप स्रोत-प्रविष्टियों को संशोधित करना शुरू करते हैं, यह स्पष्ट रूप से लक्ष्य को अपडेट नहीं करेगा क्योंकि मुझे उचित डाटाबेसिंग तंत्र की कमी है।

मैं sourceArray देख कर मैन्युअल targetArray अद्यतन करने की आवश्यकता है या कोणीय द्वारा कार्यान्वित 1-वे-बाइंडिंग तंत्र के किसी भी प्रकार जो मैं दो सरणियों सिंक्रनाइज़ रखने के लिए उपयोग कर सकते हैं करते हैं?

+0

यह सबसे अच्छा है अगर आप जवाब यहां से कुछ के रूप में अतिरिक्त $ घड़ियों से बचने के है पता चला है। यह एक कामकाज है लेकिन स्केलिंग के दौरान प्रदर्शन की लागत पर। कोणीय _does_ एक तरफ डेटा बाध्यकारी प्रदान करता है। यहां एक लिंक दिया गया है यदि आप जानना चाहते हैं कि यह कैसे काम करता है https://toddmotto.com/one-way-data-binding-in-angular-1-5/ –

उत्तर

1

आप $watch उपयोग करना चाहिए। और फिर आवश्यक फ़ंक्शन जोड़ें।

आप here देख सकते हैं और official documentation.

$ घड़ी (watchExpression, श्रोता, [objectEquality]); जब भी watchExpression बदलता है तो रजिस्टर्स श्रोता कॉलबैक निष्पादित किए जाने के लिए।

घड़ी कॉल को प्रत्येक डायजेस्ट पर $ digest() पर कॉल किया जाता है और उस मूल्य को वापस कर देगा जो देखा जाएगा। (watchExpression एक ही इनपुट के साथ कई बार निष्पादित होने पर अपना मान बदलना चाहिए क्योंकि इसे $ digest() द्वारा कई बार निष्पादित किया जा सकता है। यही है, watchExpression idempotent होना चाहिए।) श्रोता को केवल कहा जाता है जब से मान वर्तमान watchExpression और पिछले कॉल watchExpression के बराबर नहीं कर रहे हैं (प्रारंभिक रन के अपवाद के साथ, नीचे देखें)। असमानता असमानता,! == जावास्क्रिप्ट ऑपरेटर के माध्यम से सख्त तुलना संदर्भ के लिए, अनुसार निर्धारित किया जाता है, जब तक कि objectEquality == सच (अगले अंक देखें) जब objectEquality == सच है, watchExpression की असमानता angular.equals के अनुसार निर्धारित किया जाता है समारोह। ऑब्जेक्ट के मान को बाद में तुलना के लिए सहेजने के लिए, angular.copy फ़ंक्शन का उपयोग किया जाता है। यह इसलिए इसका मतलब कि जटिल वस्तुओं देख प्रतिकूल स्मृति है और निहितार्थ प्रदर्शन होगा। यह में परिवर्तनों के लिए देखने के लिए उपयोग नहीं किया जाना चाहिए जो angular.copy के साथ सीमाओं के कारण फ़ाइल ऑब्जेक्ट्स या हैं। घड़ी श्रोता मॉडल है, जो आग की अन्य श्रोताओं गति प्रदान कर सकते बदल सकते हैं। यह परिवर्तनों का पता चला है जब तक देखने वालों को पुन: प्रयास करके हासिल किया जाता है। अनंत लूप डेडलॉक को रोकने के लिए पुनरावृत्ति पुनरावृत्ति सीमा 10 है। अगर आप $कहलाते हैं तो आप अधिसूचित होना चाहते हैं, तो आप कोई श्रोता के साथ watchExpression फ़ंक्शन पंजीकृत कर सकते हैं। (अपने watchExpression को कई कॉल के लिए तैयार रहें, क्योंकि यह एक भी $ पचाने चक्र में कई बार निष्पादित करेंगे अगर एक परिवर्तन का पता चला है।)

के बाद एक द्रष्टा गुंजाइश के साथ पंजीकृत है, श्रोता fn कहा जाता है दर्शक को प्रारंभ करने के लिए असीमित रूप से (evalAsync के माध्यम से)। दुर्लभ मामलों में, यह अवांछनीय क्योंकि श्रोता कहा जाता है जब watchExpression का परिणाम परिवर्तन नहीं किया है। श्रोता fn के भीतर इस परिदृश्य को का पता लगाने के लिए, आप newVal और oldVal की तुलना कर सकते हैं।यदि ये दो मान समान हैं (===) तो श्रोता को प्रारंभिकरण के लिए कहा गया था।

3

जैसा कि प्रीतम ने कहा। आपको $ घड़ी का उपयोग करना चाहिए। लेकिन इसे काम करने के लिए, संग्रह को बांधना चाहिए। और घड़ी के अंदर सरणी मर्ज करें।

इस काम के नमूने खोजें:

$scope.$watchCollection(angular.bind(this, function() { 
    return this.sourceArray;}), function (newVal, oldVal) { 

     var arr = []; 
     for(var i in vm.sourceArray){ 
     var shared = false; 
     for (var j in vm.targetArray) 
      if (vm.targetArray[j].id == vm.sourceArray[i].id) { 
       shared = true; 
       break; 
      } 
     if(!shared) arr.push(vm.sourceArray[i]) 
     } 
     console.log(arr); 
     vm.targetArray = vm.targetArray.concat(arr); 
    },true); 

http://plnkr.co/edit/E2inRLtwfWnb1VBymNNl?p=preview

1

आप $ उपयोग कर सकते हैं अभिव्यक्ति को देखते हैं।

यहाँ डाउनलोड Underscore.js या CDN :-(एक और तरीका)

http://plnkr.co/edit/hrOrEdaQ0M7wEgWlRHlO?p=preview

  1. Angular.js कॉपी (angular.copy()) विधि है।
  2. underscore.js विधि का विस्तार करें।

    var app = angular.module('plunker', []); 
        app.controller('MainCtrl', function($scope) { 
         var vm = this; 
         vm.sourceArray = [{id: '0', name: 'someObject'}, {id: '1', name: 'anotherObject'}]; 
         vm.targetArray = angular.copy(vm.sourceArray); 
         // angular.copy(vm.sourceArray, vm.targetArray); 
         vm.push = function(){ 
          let found = false; 
          angular.forEach(vm.sourceArray, function(el){ 
          if (el.id === vm.id){ 
           el.name = vm.name; 
           found = true; 
          } 
          }); 
          if (!found){ 
          vm.sourceArray.push({id: vm.id, name: vm.name}); 
          _.extend(vm.targetArray, vm.sourceArray); 
          } 
    
        }; 
    
    
    
    vm.pushTarget = function(){ 
        let found = false; 
        angular.forEach(vm.targetArray, function(el){ 
        if (el.id === vm.id1){ 
         el.name = vm.name1; 
         found = true; 
        } 
        }); 
        if (!found){ 
        console.log({id: vm.id, name: vm.name}) 
        vm.targetArray.push({id: vm.id1, name: vm.name1}); 
        } 
    
    }; 
    

    });

आप Underscore.js कोड प्राप्त कर सकते हैं: -

_.extend = createAssigner(_.allKeys); 

// An internal function for creating assigner functions. 
var createAssigner = function(keysFunc, undefinedOnly) { 
    return function(obj) { 
     var length = arguments.length; 
     if (length < 2 || obj == null) return obj; 
     for (var index = 1; index < length; index++) { 
     var source = arguments[index], 
      keys = keysFunc(source), 
      l = keys.length; 
     for (var i = 0; i < l; i++) { 
      var key = keys[i]; 
      if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; 
     } 
     } 
     return obj; 
    }; 
    }; 

    // Retrieve all the property names of an object. 
    _.allKeys = function(obj) { 
    if (!_.isObject(obj)) return []; 
    var keys = []; 
    for (var key in obj) keys.push(key); 
    // Ahem, IE < 9. 
    if (hasEnumBug) collectNonEnumProps(obj, keys); 
    return keys; 
    }; 

    // Extend a given object with all the properties in passed-in object(s). 
1

यहाँ एक टुकड़ा मैंने बनाया है। नोट करें जब स्रोत सरणी बदलती है तो दोनों सरणी प्रभावित होती हैं, हालांकि जब आप केवल लक्ष्य को बदलते हैं तो स्रोत बरकरार रहता है।

angular.module('app', []) 
 
    .controller('mainCtrl', function($scope) { 
 
    var vm = this; 
 
    vm.sourceArray = []; 
 
    vm.source = '["change me!",{"a":3},[100]]'; 
 

 
    $scope.$watch('vm.source', function(newVal) { 
 
     try { 
 
     vm.sourceArray = JSON.parse(newVal); 
 
     vm.target = newVal; 
 
     vm.serr = null; 
 
     } catch (e) { 
 
     vm.serr = 'Invalid JSON'; 
 
     } 
 
    }); 
 
    
 
    $scope.$watch('vm.target', function(newVal) { 
 
     try { 
 
     vm.targetArray = JSON.parse(newVal); 
 
     vm.terr = null; 
 
     } catch (e) { 
 
     vm.terr = 'Invalid JSON'; 
 
     } 
 
    }); 
 

 
    //Copy whole array on change 
 
    $scope.$watch('vm.sourceArray', function(newVal) { 
 
     vm.targetArray = angular.copy(newVal); 
 
    }, true); 
 

 
    return this; 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="app" ng-controller="mainCtrl as vm"> 
 
    <span>Change the inputs one at a time to see the changes take effect</span> 
 
    <h5>Source:</h5> 
 
    <input type="text" ng-model="vm.source" ng-model-options="{debounce: 300}" placeholder="Enter json formatted string for source array"><span>{{vm.serr}}</span> 
 
    <div>Model: {{vm.sourceArray|json:null:2}}</div> 
 
    <br> 
 
    <h5>Target:</h5> 
 
    <input type="text" ng-model="vm.target" ng-model-options="{debounce: 300}" placeholder="Enter json formatted string for source array"><span>{{vm.terr}}</span> 
 
    <div>Model: {{vm.targetArray|json:null:2}}</div> 
 
</div>