ฉันจะใช้ $ rootScope ใน Angular เพื่อเก็บตัวแปรได้อย่างไร


217

ฉันจะใช้$rootScopeเพื่อเก็บตัวแปรในคอนโทรลเลอร์ที่ฉันต้องการเข้าถึงในคอนโทรลเลอร์อื่นได้อย่างไร? ตัวอย่างเช่น:

angular.module('myApp').controller('myCtrl', function($scope) {
  var a = //something in the scope
  //put it in the root scope
});

angular.module('myApp').controller('myCtrl2', function($scope) {
  var b = //get var a from root scope somehow
  //use var b
});

ฉันจะทำสิ่งนี้ได้อย่างไร


1
คุณควรฉีด $ rootScope ในคอนโทรลเลอร์และใช้เป็น javascript อย่างง่าย
Ajay Beniwal

30
$ rootScope ไม่ใช่วิธีที่ถูกต้องในการทำเช่นนี้ การทำให้ตัวแปรพร้อมใช้งานในคอนโทรลเลอร์หลายตัวเป็นบริการที่มีประโยชน์
Steve

11
@Steve: คำถามที่พบบ่อยของ Angularกล่าวว่า "อย่าสร้างบริการที่มีจุดประสงค์เพียงอย่างเดียวในชีวิตคือการจัดเก็บและคืนบิตข้อมูล" ซึ่งจะทำให้โหลดมากเกินไปในวงจรย่อย $ ..
Marwen Trabelsi

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

2
ดีเพราะไม่ได้ฉีดของคุณจะต้องเข็มฉีดยาที่ .. ก
Xsmael

คำตอบ:


248

ตัวแปรที่ตั้งค่าที่ขอบเขตของรูตจะมีให้สำหรับขอบเขตของตัวควบคุมผ่านการรับมรดกทางต้นแบบ

นี่คือเวอร์ชันสาธิตที่ได้รับการแก้ไขของ @ Nitish ซึ่งแสดงให้เห็นถึงความสัมพันธ์ที่ชัดเจนยิ่งขึ้น: http://jsfiddle.net/TmPk5/6/

โปรดสังเกตว่าตัวแปรของ rootScope ถูกตั้งค่าเมื่อโมดูลเริ่มต้นจากนั้นแต่ละขอบเขตที่สืบทอดจะได้รับสำเนาของตนเองซึ่งสามารถตั้งค่าได้อย่างอิสระ ( changeฟังก์ชัน) นอกจากนี้ค่าของ rootScope ก็สามารถปรับปรุงได้เช่นกัน ( changeRsฟังก์ชันในmyCtrl2)

angular.module('myApp', [])
.run(function($rootScope) {
    $rootScope.test = new Date();
})
.controller('myCtrl', function($scope, $rootScope) {
  $scope.change = function() {
        $scope.test = new Date();
    };

    $scope.getOrig = function() {
        return $rootScope.test;
    };
})
.controller('myCtrl2', function($scope, $rootScope) {
    $scope.change = function() {
        $scope.test = new Date();
    };

    $scope.changeRs = function() {
        $rootScope.test = new Date();
    };

    $scope.getOrig = function() {
        return $rootScope.test;
    };
});

7
บวก 1 สำหรับ ... เอ่อ ... ตอบคำถามของ OP จริง ๆ (แม้ว่า @MBielski และอื่น ๆ นั้นถูกต้อง)
แร็พ

ถ้าฉันทำสิ่ง$scope.test = 'Some value'นั้นจะ$rootScope.testเปลี่ยนแปลงเช่นกันหรือไม่
Allen Linatoc

@AllenLinatoc ไม่มันเคยชินพวกเขาเป็นสองวัตถุที่แตกต่างแม้ว่าขอบเขตของ$rootScope เป็น บริษัท ระดับโลก (มากกว่าควบคุมทั้งหมด) แต่$scopeยังคงอยู่ในท้องถิ่นที่จะควบคุม หากคุณใช้ $scope.testตัวควบคุมที่แตกต่างกันสองตัวให้รู้ว่าพวกเขาเป็นตัวแปรที่แตกต่างกันสองตัวไม่ว่า$rootScope.test จะเป็นตัวแปรตัวเดียวกันในตัวควบคุมทั้งหมดหรือไม่
Xsmael

ฉันสมมติว่าคุณไม่ต้องการใช้ $ rootScope บ่อยด้วยเหตุผลเดียวกันกับที่คุณจะไม่ใช้ตัวแปรทั่วโลกในภาษาอื่น?
Zypps987

เราสามารถสร้างตัวแปร rootcope จำนวนเท่าใดในแอป
Jay

161

การแชร์ข้อมูลระหว่างคอนโทรลเลอร์เป็นสิ่งที่โรงงาน / บริการดีมาก ในระยะสั้นมันทำงานอะไรเช่นนี้

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

app.factory('items', function() {
    var items = [];
    var itemsService = {};

    itemsService.add = function(item) {
        items.push(item);
    };
    itemsService.list = function() {
        return items;
    };

    return itemsService;
});

function Ctrl1($scope,items) {
    $scope.list = items.list; 
}

function Ctrl2($scope, items) {
    $scope.add = items.add;
}

คุณสามารถดูตัวอย่างการทำงานได้ในซอ: http://jsfiddle.net/mbielski/m8saa/


49
+1 $rootScopeไม่ควรใช้เพื่อแชร์ตัวแปรเมื่อเรามีสิ่งต่าง ๆ เช่นบริการและโรงงาน
jjperezaguinaga

74
คำถามที่พบบ่อยเกี่ยวกับ Angular กล่าวไว้ที่ด้านล่างของหน้า: "ในทางกลับกันอย่าสร้างบริการที่มีจุดประสงค์เพียงอย่างเดียวในชีวิตคือการจัดเก็บและส่งคืนข้อมูล ดู: docs.angularjs.org/misc/faq
Oytun

11
นี่เป็นตัวอย่างง่ายๆ ฉันเชื่อว่าพวกเขากำลังบอกว่าจะไม่มีบริการที่ปรากฏในคอนโทรลเลอร์เดียวเท่านั้น ฉันไม่สามารถนับจำนวนพนักงานที่พัฒนา Angular ได้กล่าวว่าบริการเป็นวิธีที่เป็นทางการในการส่งผ่านข้อมูลระหว่างคอนโทรลเลอร์ ดูรายชื่อผู้รับจดหมายถามผู้ทรงคุณวุฒิเชิงมุมและดูว่าคุณได้รับอะไรบ้าง ฉันอาจทราบด้วยว่าคำพูดของคุณอยู่ที่ด้านล่างของหัวข้อชื่อ "$ rootScope มีอยู่ แต่สามารถใช้เพื่อความชั่วร้ายได้" การส่งข้อมูลจากคอนโทรลเลอร์หนึ่งไปยังอีกคอนโทรลเลอร์หนึ่งนั้นเป็นความชั่วร้าย
MBielski

1
แต่ถ้าคุณต้องการวนลูปแม้ว่าไอเท็มของคุณในมุมมอง / คอนโทรลเลอร์ที่แตกต่างกันสองรายการคุณต้องคัดลอกข้อมูลก่อนในคอนโทรลเลอร์เพื่อให้มันดู (ฉันเชื่อว่านี่คือ $ rootScope แก้ไข)
Thomas Decaux

1
มันขึ้นอยู่กับนักพัฒนาที่จะใช้วิจารณญาณว่าควรใช้บริการหรือแก้ไขด่วนของ rootScope สำหรับบางสิ่งขอบเขตทั่วโลกเป็นสิ่งอำนวยความสะดวกและสะดวกในการใช้งาน - และฉันคิดว่าสิ่งที่เอกสารเชิงมุมกำลังพยายามพูด ช่วยให้ศิลปะในการเขียนโปรแกรมและไม่กลายเป็นหุ่นยนต์กับ MVC blah blah blah ทั้งหมด คุณอาจใช้บริการข้างต้นและ $ เฝ้าดูตัวแปรหากคุณต้องการคอนโทรลเลอร์หนึ่งตัวเพื่อทราบเกี่ยวกับการเปลี่ยนแปลงอย่างไรก็ตามเนื่องจากมันอยู่ที่นี่มันไม่ได้สื่อสารกันระหว่างตัวควบคุมจริงๆ
ลงจอด

21
angular.module('myApp').controller('myCtrl', function($scope, $rootScope) {
   var a = //something in the scope
   //put it in the root scope
    $rootScope.test = "TEST";
 });

angular.module('myApp').controller('myCtrl2', function($scope, $rootScope) {
   var b = //get var a from root scope somehow
   //use var b

   $scope.value = $rootScope.test;
   alert($scope.value);

 //    var b = $rootScope.test;
 //  alert(b);
 });

การสาธิต


ดังนั้นใน Angular คุณมักจะไม่ใช้ var?
trysis

1
มันขึ้นอยู่กับสภาพ หากต้องการแสดงใน html แล้วคุณจำเป็นต้องใช้มิฉะนั้นคุณสามารถใช้ var
Nitish Kumar

โอ้ขอบเขตสำหรับสิ่งที่ DOM?
trysis

1
สิ่งนี้อาจจะล่าช้า แต่สำหรับผู้มาสายช้า ๆ ขอบเขตคือกาวระหว่างมุมมองและตัวควบคุมตามเอกสาร AJS ขอบเขตไม่ได้อ้างอิง DOM โดยตรง ถ้าเช่นนั้นจะเป็นอย่างไร นี่คือเอกสารที่ละเอียดยิ่งขึ้น docs.angularjs.org/guide/scope
yantaq

9

ฉันหาเหตุผลที่จะทำ $ scope.value = $ rootScope.test;

$ scope เป็นตัวอย่างที่สืบทอดมาจาก $ rootScope

โปรดดูตัวอย่างนี้

var app = angular.module('app',[]).run(function($rootScope){
$rootScope.userName = "Rezaul Hasan";
});

ตอนนี้คุณสามารถผูกตัวแปรขอบเขตนี้ได้ทุกที่ในแท็กแอป


6

ก่อนเก็บค่าใน $ rootScope เป็น

.run(function($rootScope){
$rootScope.myData = {name : "nikhil"}
})

.controller('myCtrl', function($scope) {
var a ="Nikhilesh";
$scope.myData.name = a;
});

.controller('myCtrl2', function($scope) {
var b = $scope.myData.name;
)}

$ rootScope เป็นแหล่งกำเนิดของ $ scope ทั้งหมด $ scope แต่ละอันได้รับสำเนาของข้อมูล $ rootScope ซึ่งคุณสามารถเข้าถึงโดยใช้ $ scope เอง


3

หากเป็นเพียง "การเข้าถึงตัวควบคุมอื่น" คุณสามารถใช้ค่าคงที่เชิงมุมสำหรับสิ่งนั้นได้ประโยชน์คือ; คุณสามารถเพิ่มการตั้งค่าส่วนกลางหรือสิ่งอื่น ๆ ที่คุณต้องการเข้าถึงได้ตลอดทั้งแอปพลิเคชัน

app.constant(‘appGlobals’, {
    defaultTemplatePath: '/assets/html/template/',
    appName: 'My Awesome App'
});

แล้วเข้าถึงได้เช่น:

app.controller(‘SomeController’, [‘appGlobals’, function SomeController(config) {
    console.log(appGlobals);
    console.log(‘default path’, appGlobals.defaultTemplatePath);
}]);

(ไม่ได้ทดสอบ)

ข้อมูลเพิ่มเติม: http://ilikekillnerds.com/2014/11/constants-values-global-variables-in-angularjs-the-right-way/



1

มีหลายวิธีในการบรรลุเป้าหมายนี้: -

1.เพิ่ม$rootScopeใน.runวิธีการ

.run(function ($rootScope) {
    $rootScope.name = "Peter";
});

// Controller
.controller('myController', function ($scope,$rootScope) {
    console.log("Name in rootscope ",$rootScope.name);
    OR
    console.log("Name in scope ",$scope.name);
});

2.สร้างบริการหนึ่งรายการและเข้าถึงได้ทั้งในตัวควบคุม

.factory('myFactory', function () {
     var object = {};

     object.users = ['John', 'James', 'Jake']; 

     return object;
})
// Controller A

.controller('ControllerA', function (myFactory) {
    console.log("In controller A ", myFactory);
})

// Controller B

.controller('ControllerB', function (myFactory) {
    console.log("In controller B ", myFactory);
})
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.