AngularJS: ฉันจะส่งผ่านตัวแปรระหว่างตัวควบคุมได้อย่างไร


326

ฉันมีตัวควบคุมเชิงมุมสองตัว:

function Ctrl1($scope) {
    $scope.prop1 = "First";
}

function Ctrl2($scope) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

ฉันไม่สามารถใช้Ctrl1ภายในCtrl2เพราะมันไม่ได้กำหนด อย่างไรก็ตามถ้าฉันพยายามผ่านมันให้เป็นเช่นนั้น ...

function Ctrl2($scope, Ctrl1) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

ฉันได้รับข้อผิดพลาด ไม่มีใครรู้วิธีการทำเช่นนี้?

การทำ

Ctrl2.prototype = new Ctrl1();

ยังล้มเหลว

หมายเหตุ:ตัวควบคุมเหล่านี้ไม่ซ้อนกันภายใน


มีหลายวิธี แต่วิธีที่ดีที่สุดคือนาฬิกาเชิงมุม เสมอเมื่อเราใช้เฟรมเวิร์กเป็นวิธีที่ดีที่สุดในการใช้วิธีการของตัวเองในการทำงานอย่าลืมสิ่งนี้
pejman

ฉันพบบล็อกนี้มีประโยชน์มากบล็อก
Black Mamba

คำตอบ:


503

วิธีหนึ่งในการแบ่งปันตัวแปรข้ามตัวควบคุมหลายตัวคือการสร้างบริการและฉีดเข้าไปในตัวควบคุมที่คุณต้องการใช้

ตัวอย่างบริการที่เรียบง่าย:

angular.module('myApp', [])
    .service('sharedProperties', function () {
        var property = 'First';

        return {
            getProperty: function () {
                return property;
            },
            setProperty: function(value) {
                property = value;
            }
        };
    });

การใช้บริการในคอนโทรลเลอร์:

function Ctrl2($scope, sharedProperties) {
    $scope.prop2 = "Second";
    $scope.both = sharedProperties.getProperty() + $scope.prop2;
}

นี่เป็นคำอธิบายที่ดีมากในบล็อกนี้ (โดยเฉพาะอย่างยิ่งบทที่ 2 และโดยเฉพาะ)

ฉันพบว่าถ้าคุณต้องการผูกคุณสมบัติเหล่านี้ข้ามคอนโทรลเลอร์หลายตัวมันจะทำงานได้ดีกว่าถ้าคุณผูกเข้ากับคุณสมบัติของวัตถุแทนที่จะเป็นชนิดดั้งเดิม (บูลีน, สตริง, ตัวเลข) เพื่อคงการอ้างอิงที่ถูกผูกไว้

ตัวอย่าง: แทนvar property = { Property1: 'First' };var property = 'First';


ปรับปรุง:เพื่อ (หวังว่า) ทำให้สิ่งที่ชัดเจนมากขึ้นที่นี่เป็นซอที่แสดงตัวอย่างของ:

  • การเชื่อมโยงกับสำเนาแบบคงที่ของค่าที่แชร์ (ใน myController1)
    • เข้าเล่มแบบดั้งเดิม (สตริง)
    • เชื่อมโยงกับคุณสมบัติของวัตถุ (บันทึกลงในตัวแปรขอบเขต)
  • เชื่อมโยงกับค่าที่ใช้ร่วมกันซึ่งอัปเดต UI เป็นค่าที่ได้รับการปรับปรุง (ใน myController2)
    • เชื่อมโยงกับฟังก์ชันที่ส่งคืนค่าดั้งเดิม (สตริง)
    • เชื่อมโยงกับคุณสมบัติของวัตถุ
    • มีผลผูกพันสองทางกับคุณสมบัติของวัตถุ

5
ในกรณีนี้ - ขอบเขตของ Ctrl2 "รู้" เมื่อ sharedProperties.getProperty () เปลี่ยนแปลงค่าอย่างไร
OpherV

5
หากคุณต้องการให้ UI ของคุณอัปเดตทุกครั้งที่การเปลี่ยนแปลงคุณสมบัติคุณสามารถเปลี่ยนbothเป็นฟังก์ชันได้และจะมีการเรียก / ประเมินใหม่ในระหว่างกระบวนการแยกย่อยแบบเชิงมุม ดูซอนี้เป็นตัวอย่าง นอกจากนี้หากคุณเชื่อมโยงกับคุณสมบัติของวัตถุคุณสามารถใช้งานได้โดยตรงในมุมมองของคุณและจะอัปเดตเนื่องจากข้อมูลมีการเปลี่ยนแปลงคล้ายกับตัวอย่างนี้
Gloopy

11
หากคุณต้องการตรวจจับและตอบสนองต่อการเปลี่ยนแปลงในตัวควบคุมของคุณตัวเลือกคือการเพิ่มgetProperty()ฟังก์ชั่นในขอบเขตและใช้$ scope $ watchเหมือนในตัวอย่างนี้ หวังว่าตัวอย่างเหล่านี้จะช่วยได้!
Gloopy

1
มีปัญหาที่นี่เนื่องจากบริการควรไร้สัญชาติ การจัดเก็บทรัพย์สินภายในบริการไม่ถูกต้อง (แต่สะดวก) ฉันเริ่มใช้ $ cacheFactory เพื่ออ่านและเขียนข้อมูล ฉันใช้บริการที่เหมือนกันเกือบเหมือน Gloopy แต่แทนที่จะเก็บสถานะไว้ในบริการตอนนี้อยู่ในแคช ขั้นแรกสร้างบริการแคช: angular.module ('CacheService', ['ng']) .factory ('CacheService', ฟังก์ชั่น ($ cacheFactory) {ส่งกลับ $ cacheFactory ('CacheService');}); รวมไว้ใน app.js ของคุณฉีดเข้าไปในบริการใช้เหมือน: return CacheService.get (กุญแจ); หรือ CacheService.put (คีย์, ค่า);
Jordan Papaleo

4
พยายามที่จะค้นหาว่าทำไมคำตอบนี้จึงใช้.serviceแทน.factoryคำอธิบายในเอกสารเชิงมุม ทำไมคำตอบนี้ถึงได้คะแนนสูงมากเมื่อเอกสารใช้วิธีการอื่น
pspahn

44

ฉันชอบที่จะอธิบายสิ่งที่เรียบง่ายด้วยตัวอย่างง่ายๆ :)

นี่เป็นServiceตัวอย่างง่ายๆ:


angular.module('toDo',[])

.service('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  this.dataObj = _dataObj;
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

และนี่คือ jsbin

และนี่คือFactoryตัวอย่างง่ายๆ:


angular.module('toDo',[])

.factory('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  return {
    dataObj: _dataObj
  };
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

และนี่คือ jsbin


หากนั่นง่ายเกินไปนี่คือตัวอย่างที่ซับซ้อนมากขึ้น

นอกจากนี้ยังเห็นคำตอบที่นี่เพื่อที่เกี่ยวข้องกับการปฏิบัติที่ดีที่สุดของการแสดงความคิดเห็น


1
ใช่ฉันเห็นด้วยกับคุณ. พยายามทำให้ทุกอย่างเป็นเรื่องง่ายเสมอ
Evan Hu

จุดประสงค์ในการประกาศคืออะไรvar _dataObj = {};เมื่อคุณส่งคืนการอ้างอิงโดยตรงไปยัง .. ที่ไม่ได้เป็นส่วนตัว ในตัวอย่างแรกคุณสามารถทำได้this.dataObj = {};และในครั้งที่สองreturn { dataObj: {} };เป็นการประกาศตัวแปรที่ไร้ประโยชน์ IMHO
TJ

@TJ จุดคือการแบ่งปันตัวแปรนี้ในหมู่องค์ประกอบอื่น ๆ มันเป็นตัวอย่างพื้นฐานที่แสดงแนวคิดของการแบ่งปัน ตัวแปร IS เป็นส่วนตัวภายในบล็อกจากนั้นคุณเปิดเผยเป็นตัวแปรสาธารณะโดยใช้รูปแบบการเปิดเผย วิธีนี้มีการแบ่งแยกความรับผิดชอบระหว่างการถือครองตัวแปรและการใช้งานมัน
Dmitri Zaitsev

@DmitriZaitsev คุณพูดว่า "ตัวอย่างง่ายๆ" แต่ถ้าคุณไม่แสดงวิธีการใช้ประโยชน์จากสถานะส่วนตัวอย่างถูกต้องคุณก็แค่ทำให้คนสับสน ไม่มีสถานะส่วนตัวในตัวอย่างของคุณตราบใดที่คุณส่งคืนการอ้างอิงโดยตรง
TJ

@TJ ฉันไม่เห็นอะไรสับสน ตัวแปรส่วนตัวสามารถเปิดเผยโดยโมดูล อย่าลังเลที่จะเขียนคำตอบที่ดีกว่า
Dmitri Zaitsev

26

--- ฉันรู้ว่าคำตอบนี้ไม่ได้สำหรับคำถามนี้ แต่ฉันต้องการคนที่อ่านคำถามนี้และต้องการจัดการบริการต่าง ๆ เช่นโรงงานเพื่อหลีกเลี่ยงปัญหาในการทำเช่นนี้ ----

สำหรับสิ่งนี้คุณจะต้องใช้บริการหรือโรงงาน

บริการเป็นแนวทางปฏิบัติที่ดีที่สุดในการแบ่งปันข้อมูลระหว่างตัวควบคุมที่ไม่ซ้อนกัน

หมายเหตุประกอบที่ดีมากในหัวข้อนี้เกี่ยวกับการแบ่งปันข้อมูลคือวิธีการประกาศวัตถุ ฉันโชคไม่ดีเพราะฉันตกหลุมพราง AngularJS ก่อนที่ฉันจะอ่านเกี่ยวกับเรื่องนี้และฉันก็ผิดหวังมาก ดังนั้นให้ฉันช่วยคุณหลีกเลี่ยงปัญหานี้

ฉันอ่านจาก "ng-book: หนังสือที่สมบูรณ์เกี่ยวกับ AngularJS" ที่ AngularJS รุ่น ng ที่สร้างขึ้นในตัวควบคุมเนื่องจากไม่มีข้อมูล!

องค์ประกอบ $ scope ควรสร้างเช่นนี้

angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
  // best practice, always use a model
  $scope.someModel = {
    someValue: 'hello computer'
  });

และไม่ชอบสิ่งนี้:

angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
  // anti-pattern, bare value
  $scope.someBareValue = 'hello computer';
  };
});

นี่เป็นเพราะมันได้รับการแนะนำ (ปฏิบัติที่ดีที่สุด) สำหรับ DOM (เอกสาร html) เพื่อให้มีการโทรเป็น

<div ng-model="someModel.someValue"></div>  //NOTICE THE DOT.

สิ่งนี้มีประโยชน์มากสำหรับตัวควบคุมที่ซ้อนกันถ้าคุณต้องการให้ตัวควบคุมลูกของคุณสามารถเปลี่ยนวัตถุจากตัวควบคุมหลัก ...

แต่ในกรณีของคุณคุณไม่ต้องการขอบเขตที่ซ้อนกัน แต่มีแง่มุมที่คล้ายกันในการรับวัตถุจากบริการไปยังตัวควบคุม

ให้บอกว่าคุณมี 'โรงงาน' บริการของคุณและในพื้นที่ส่งคืนมี objectA ที่มี objectB ที่มี objectC

หากจากคอนโทรลเลอร์คุณต้องการรับ objectC ในขอบเขตของคุณเป็นความผิดพลาดที่จะพูด

$scope.neededObjectInController = Factory.objectA.objectB.objectC;

มันใช้งานไม่ได้ ... ใช้จุดเดียวแทน

$scope.neededObjectInController = Factory.ObjectA;

จากนั้นใน DOM คุณสามารถเรียก objectC จาก objectA นี่คือแนวปฏิบัติที่ดีที่สุดเกี่ยวกับโรงงานและที่สำคัญที่สุดจะช่วยหลีกเลี่ยงข้อผิดพลาดที่ไม่คาดคิดและไม่สามารถตรวจจับได้


2
ฉันคิดว่านี่เป็นคำตอบที่ดี แต่มันยากที่จะแยกแยะ
pspahn

17

โซลูชันโดยไม่ต้องสร้างบริการโดยใช้ $ rootScope:

ในการแชร์คุณสมบัติต่าง ๆ ผ่านแอพคอนโทรลเลอร์คุณสามารถใช้ Angular $ rootScope นี่เป็นอีกหนึ่งตัวเลือกในการแชร์ข้อมูลวางไว้เพื่อให้ผู้คนรู้ได้

วิธีที่ต้องการในการแบ่งปันฟังก์ชั่นบางอย่างในส่วนควบคุมคือบริการเพื่ออ่านหรือเปลี่ยนแปลงคุณสมบัติทั่วโลกที่คุณสามารถใช้ $ rootcope

var app = angular.module('mymodule',[]);
app.controller('Ctrl1', ['$scope','$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = true;
}]);

app.controller('Ctrl2', ['$scope','$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = false;
}]);

การใช้ $ rootScope ในเทมเพลต (คุณสมบัติการเข้าถึงที่มี $ root):

<div ng-controller="Ctrl1">
    <div class="banner" ng-show="$root.showBanner"> </div>
</div>

5
คุณกำลังใช้ตัวแปรที่มีการกำหนดขอบเขตทั่วโลก ณ จุดนั้นซึ่งเบี่ยงเบนไปจากแนวคิด AngularJS ของการกำหนดขอบเขตทุกอย่างภายในโครงสร้างที่หลากหลาย การเพิ่มไฟล์ตัวแปรโกลบอลจะทำให้ได้สิ่งเดียวกันและทำให้ง่ายต่อการค้นหาตำแหน่งที่ตัวแปรนั้นถูกกำหนดไว้ตั้งแต่แรก ทั้งสองวิธีไม่แนะนำ
Organiccat

4
@Organiccat - ฉันเข้าใจความกังวลของคุณและนั่นเป็นเหตุผลที่ฉันได้กล่าวแล้วว่าวิธีที่ต้องการจะให้บริการไม่ต้องสงสัยเลยว่า แต่ยาเชิงมุมก็ให้วิธีนี้เช่นกัน เป็นไปตามที่คุณต้องการจัดการโลกของคุณ ฉันมีสถานการณ์ที่วิธีการนี้ทำงานได้ดีที่สุดสำหรับฉัน
Sanjeev

8

ตัวอย่างข้างต้นทำงานได้อย่างมีเสน่ห์ ฉันเพิ่งทำการแก้ไขในกรณีที่ฉันต้องจัดการหลายค่า ฉันหวังว่านี่จะช่วยได้!

app.service('sharedProperties', function () {

    var hashtable = {};

    return {
        setValue: function (key, value) {
            hashtable[key] = value;
        },
        getValue: function (key) {
            return hashtable[key];
        }
    }
});

1
ฉันยังสร้างตัวอย่างโดยใช้บริการเพื่อแชร์ข้อมูลข้ามคอนโทรลเลอร์ที่แตกต่างกัน ฉันหวังว่าพวกคุณจะชอบมัน jsfiddle.net/juazammo/du53553a/1
Juan Zamora

1
.factoryแม้ว่ามันจะทำงานนี้มักจะไวยากรณ์สำหรับ .serviceควรใช้ "ถ้าคุณกำหนดบริการของคุณเป็นประเภท / ระดับ" เป็นต่อdocs.angularjs.org/api/auto/service/$provide#service
Dmitri Zaitsev

1
Dmitri คุณพูดถูก แต่อย่างไรก็ตามพวก Angular จากมุมมองของฉันเพิ่งเปลี่ยนแนวคิดเล็กน้อยที่ฉันมีระหว่างการบริการ (ด้านหน้า) และโรงงาน .... โอ้ดี ....
Juan Zamora

1
และแก้ไขให้ถูกต้องหากฉันผิดบริการตั้งใจจะคืนสิ่งที่อาจเป็นวัตถุหรือของมีค่า โรงงานมีวัตถุประสงค์เพื่อสร้างวัตถุ facace ซึ่งอันที่จริงเป็นคอลเลกชันของฟังก์ชันที่คืนสิ่งที่ฉันคิดว่าบริการที่ รวมถึงการเรียกใช้ฟังก์ชันจากโรงงาน อีกครั้งที่ฉันได้รับแนวคิดพื้นฐานของสิ่งนี้สำหรับฉันและไม่ใช่สิ่งที่เป็นจริงจากมุมมองเชิงมุม (Abstract Factory dofactory.com/net/abstract-factory-design-pattern ) และวิธีการใช้อะแดปเตอร์คือสิ่งที่ฉันจะเปิดเผยในการให้บริการ
Juan Zamora

1
ตรวจสอบรูปแบบของการ์ดได้ที่นี่dofactory.com/net/adapter-design-pattern
Juan Zamora

6

ฉันมักจะใช้ค่านิยมมีความสุขสำหรับทุกคนที่จะพูดคุยว่าทำไมนี่เป็นความคิดที่ไม่ดี ..

var myApp = angular.module('myApp', []);

myApp.value('sharedProperties', {}); //set to empty object - 

จากนั้นฉีดค่าตามบริการ

ตั้งอยู่ใน ctrl1:

myApp.controller('ctrl1', function DemoController(sharedProperties) {
  sharedProperties.carModel = "Galaxy";
  sharedProperties.carMake = "Ford";
});

และการเข้าถึงจาก ctrl2:

myApp.controller('ctrl2', function DemoController(sharedProperties) {
  this.car = sharedProperties.carModel + sharedProperties.carMake; 

});

สิ่งนี้แตกต่างจากการใช้บริการอย่างไร
dopatraman

5

ตัวอย่างต่อไปนี้แสดงวิธีการส่งตัวแปรระหว่างตัวควบคุมพี่น้องและดำเนินการเมื่อค่าเปลี่ยนแปลง

ใช้ตัวอย่างกรณี: คุณมีตัวกรองในแถบด้านข้างที่เปลี่ยนแปลงเนื้อหาของมุมมองอื่น

angular.module('myApp', [])

  .factory('MyService', function() {

    // private
    var value = 0;

    // public
    return {
      
      getValue: function() {
        return value;
      },
      
      setValue: function(val) {
        value = val;
      }
      
    };
  })
  
  .controller('Ctrl1', function($scope, $rootScope, MyService) {

    $scope.update = function() {
      MyService.setValue($scope.value);
      $rootScope.$broadcast('increment-value-event');
    };
  })
  
  .controller('Ctrl2', function($scope, MyService) {

    $scope.value = MyService.getValue();

    $scope.$on('increment-value-event', function() {    
      $scope.value = MyService.getValue();
    });
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  
  <h3>Controller 1 Scope</h3>
  <div ng-controller="Ctrl1">
    <input type="text" ng-model="value"/>
    <button ng-click="update()">Update</button>
  </div>
  
  <hr>
  
  <h3>Controller 2 Scope</h3>
  <div ng-controller="Ctrl2">
    Value: {{ value }}
  </div>  

</div>


4

ฉันต้องการมีส่วนร่วมในคำถามนี้โดยชี้ให้เห็นว่าวิธีที่แนะนำในการแบ่งปันข้อมูลระหว่างตัวควบคุมและแม้แต่คำสั่งคือการใช้บริการ (โรงงาน) ตามที่ได้ชี้ไปแล้ว แต่ฉันต้องการที่จะให้ ตัวอย่างการทำงานจริงของวิธีการที่ควรทำ

นี่คือพลั่วเกอร์ที่ทำงาน: http://plnkr.co/edit/Q1VdKJP2tpvqqJL1LF6m?p=info

ก่อนอื่นให้สร้างบริการของคุณซึ่งจะมีข้อมูลที่แชร์ของคุณ:

app.factory('SharedService', function() {
  return {
    sharedObject: {
      value: '',
      value2: ''
    }
  };
});

จากนั้นเพียงฉีดลงบนคอนโทรลเลอร์ของคุณและหยิบข้อมูลที่แชร์ในขอบเขตของคุณ:

app.controller('FirstCtrl', function($scope, SharedService) {
  $scope.model = SharedService.sharedObject;
});

app.controller('SecondCtrl', function($scope, SharedService) {
  $scope.model = SharedService.sharedObject;
});

app.controller('MainCtrl', function($scope, SharedService) {
  $scope.model = SharedService.sharedObject;
});

คุณยังสามารถทำเช่นนั้นสำหรับคำสั่งของคุณมันทำงานในลักษณะเดียวกัน:

app.directive('myDirective',['SharedService', function(SharedService){
  return{
    restrict: 'E',
    link: function(scope){
      scope.model = SharedService.sharedObject;
    },
    template: '<div><input type="text" ng-model="model.value"/></div>'
  }
}]);

หวังว่าคำตอบที่เป็นประโยชน์และสะอาดนี้จะเป็นประโยชน์กับใครบางคน


3

คุณสามารถทำได้ด้วยบริการหรือโรงงาน มันแตกต่างกันโดยพื้นฐานสำหรับความแตกต่างหลัก ๆ ฉันพบคำอธิบายนี้ในthinkster.ioเพื่อให้ง่ายที่สุดในการติดตาม ง่ายตรงประเด็นและมีประสิทธิภาพ


1
"คุณสามารถทำเช่นนั้นกับบริการหรือโรงงาน" - ได้อย่างไร .. ? ทำอย่างไรเป็นสิ่งที่ OP ขอ ... กรุณาโพสต์คำตอบที่สมบูรณ์ใน stackoverflow ตัวเองแทนที่จะเชื่อมโยงไปยังแหล่งข้อมูลภายนอกลิงก์อาจทำงานล่วงเวลา
TJ

2

คุณไม่สามารถทำให้คุณสมบัติเป็นส่วนหนึ่งของขอบเขตขอบเขตได้หรือไม่

$scope.$parent.property = somevalue;

ฉันไม่ได้บอกว่ามันถูกต้อง แต่ใช้งานได้


3
NOTE: These controllers are not nested inside each other.ผู้เขียนกล่าวว่า หากสิ่งเหล่านี้เป็นตัวควบคุมที่ซ้อนกันหรือตัวควบคุมที่ใช้แม่แบบเดียวกันนี้จะทำงานได้ แต่เราไม่สามารถคาดหวังได้
Chris Foster

2
โดยทั่วไปแล้วเป็นวิธีปฏิบัติที่ไม่ดีที่ต้องพึ่งพา$parentหากสามารถหลีกเลี่ยงได้ ส่วนประกอบที่สามารถนำกลับมาใช้ใหม่ที่ออกแบบมาอย่างดีไม่ควรรู้เกี่ยวกับพ่อแม่ของมัน
Dmitri Zaitsev

2

อามีสิ่งใหม่นี้เป็นอีกทางเลือกหนึ่ง มันเป็นหน่วยงานท้องถิ่นและทำงานที่งานเชิงมุม ไม่เป็นไร (แต่จริงๆขอบคุณผู้ชาย)

https://github.com/gsklee/ngStorage

กำหนดค่าเริ่มต้นของคุณ:

$scope.$storage = $localStorage.$default({
    prop1: 'First',
    prop2: 'Second'
});

เข้าถึงค่า:

$scope.prop1 = $localStorage.prop1;
$scope.prop2 = $localStorage.prop2;

เก็บค่าต่างๆ

$localStorage.prop1 = $scope.prop1;
$localStorage.prop2 = $scope.prop2;

อย่าลืมฉีด ngStorage ในแอปของคุณและ $ localStorage ในคอนโทรลเลอร์ของคุณ


1
วิธีนี้จะช่วยแก้ปัญหาที่แตกต่าง - ที่เก็บข้อมูลถาวร นี่ไม่ใช่วิธีแก้ปัญหาที่ปรับขนาดได้สำหรับปัญหาที่เกิดขึ้นเนื่องจากทำให้โค้ดของคุณรั่วไหลโดยมีผลข้างเคียงเช่นการปรับเปลี่ยนออบเจ็กต์ที่จัดเก็บในตัวเครื่องพร้อมช่องโหว่ของการปะทะกันของชื่อ
Dmitri Zaitsev


1

แนวทางที่สอง:

angular.module('myApp', [])
  .controller('Ctrl1', ['$scope',
    function($scope) {

    $scope.prop1 = "First";

    $scope.clickFunction = function() {
      $scope.$broadcast('update_Ctrl2_controller', $scope.prop1);
    };
   }
])
.controller('Ctrl2', ['$scope',
    function($scope) {
      $scope.prop2 = "Second";

        $scope.$on("update_Ctrl2_controller", function(event, prop) {
        $scope.prop = prop;

        $scope.both = prop + $scope.prop2; 
    });
  }
])

Html:

<div ng-controller="Ctrl2">
  <p>{{both}}</p>
</div>

<button ng-click="clickFunction()">Click</button>

สำหรับรายละเอียดเพิ่มเติมดูที่พลั่ว:

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


1
ทำงานได้เฉพาะในกรณีที่Ctrl2(ฟัง) Ctrl1เป็นตัวควบคุมเด็ก $rootScopeควบคุมพี่น้องมีการสื่อสารผ่าน
herzbube

0

หากคุณไม่ต้องการให้บริการคุณสามารถทำสิ่งนี้ได้

var scope = angular.element("#another ctrl scope element id.").scope();
scope.plean_assign = some_value;

37
ฉันไม่สงสัยเลยว่าคำตอบนี้ใช้ได้ผล แต่ฉันต้องการทราบว่าสิ่งนี้ขัดกับปรัชญาของ AngularJS ที่จะไม่มีวัตถุ DOM ในรหัสรุ่น / คอนโทรลเลอร์ของคุณ
JoeCool

3
-1 เนื่องจากการสื่อสารคอนโทรลเลอร์ผ่าน DOM เป็นวิธีปฏิบัติที่ไม่ดีในความคิดของฉัน
Chris Foster

3
@ChrisFoster เพียงเพราะค้อนถูกขายเป็น "เครื่องมือ" มันไม่ได้หมายความว่ามันไม่สามารถใช้เป็นน้ำหนักกระดาษได้ ฉันแน่ใจว่าสำหรับทุกกรอบหรือเครื่องมือออกมีคุณจะพบนักพัฒนาที่ต้อง "โค้ง" รายการ "แนวทางปฏิบัติที่ดีที่สุด"
อังเดร V

5
@AndreiV - การเปรียบเทียบไม่ดีไม่มีข้อเสียในการใช้ค้อนเป็นน้ำหนักกระดาษ การปฏิบัติที่ไม่ดีเช่นนี้มีข้อเสียที่ชัดเจนและสามารถนำไปสู่รหัสสปาเก็ตตี้ได้อย่างง่ายดาย โค้ดด้านบนนั้นบอบบางเนื่องจากตอนนี้ขึ้นอยู่กับว่าคอนโทรลเลอร์ของคุณอยู่ที่ไหนใน DOM และทดสอบได้ยากมาก การใช้บริการเป็นการปฏิบัติที่ดีกว่าด้วยเหตุผลเนื่องจากไม่ผูกติดกับการใช้งานกับแม่แบบของคุณ ฉันเห็นด้วยกับนักพัฒนามักจะต้องงอรายการปฏิบัติที่ดีที่สุด แต่ไม่ใช่เมื่อมีแนวทางปฏิบัติที่ดีที่สุดแบบแยกส่วนที่ชัดเจนทั่วไปที่ทำงานได้ดีกว่า
Chris Foster

-1

นอกเหนือจาก $ rootScope และบริการยังมีทางเลือกที่สะอาดและใช้งานง่ายเพื่อขยายมุมเพื่อเพิ่มข้อมูลที่แชร์:

ในตัวควบคุม:

angular.sharedProperties = angular.sharedProperties 
    || angular.extend(the-properties-objects);

คุณสมบัตินี้เป็นของวัตถุ 'เชิงมุม' แยกออกจากขอบเขตและสามารถใช้ร่วมกันในขอบเขตและบริการ

ข้อดีอย่างหนึ่งของการที่คุณไม่ต้องฉีดสิ่งเหล่านี้: พวกมันสามารถเข้าถึงได้ทุกที่ทันทีหลังจากการกำหนดของคุณ!


2
นี่คือเหมือนมีตัวแปรทั่วโลกมากกว่าทุกwindowวัตถุ ... ถ้าคุณกำลังจะก่อให้เกิดมลพิษเชิงมุมทำไมไม่เพียงไปข้างหน้าและก่อให้เกิดมลพิษวัตถุหน้าต่าง ...
TJ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.