ตั้งค่าตัวแปรขอบเขตเชิงมุมในมาร์กอัป


97

คำถามง่ายๆ: ฉันจะตั้งค่าขอบเขตใน html เพื่อให้คอนโทรลเลอร์ของฉันอ่านได้อย่างไร

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

app.controller('MyController', function($scope) {
  console.log($scope.myVar);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app'>
  <div ng-controller="MyController" app-myVar="test">
    {{myVar}}
  </div>
</div>

JSFiddle: http://jsfiddle.net/ncapito/YdQcX/


คุณอาจจะดีกว่าถ้าสร้างคำสั่งเพื่อจัดการสิ่งนี้ คำสั่งจะห่อหุ้ม: พารามิเตอร์ตัวควบคุมเฉพาะสำหรับคำสั่งนี้และเทมเพลตสำหรับมาร์กอัป "myMap"
Ian Mercer

นั่นคือสิ่งที่ฉันทำจริงๆ ... มีปัญหาบางอย่างในการเข้าถึง $ scope.myVar ในตัวควบคุมคำสั่ง เหตุใดฉันจึงต้องใช้นาฬิกาในคอนโทรลเลอร์เพื่อเข้าถึงตัวแปรขอบเขต
Nix

1
บางทีคุณอาจโพสต์คำสั่งของคุณ? ลองดู "การทำความเข้าใจการแปลงและขอบเขต" ที่นี่docs.angularjs.org/guide/directive คุณอาจต้องมีขอบเขต: {myVar: '='} และคุณจะพูดmy-var="foo"เมื่อคุณเรียกมัน สังเกตการใช้ยัติภังค์เทียบกับ camelCase หมายเหตุ: fooนี่คือการประเมินหากคุณไม่ต้องการให้ใช้ "@" ในการกำหนดขอบเขตเพื่อเข้าถึงค่าของแอตทริบิวต์
Ian Mercer

1
@Nix คุณสามารถอธิบายได้ไหมว่าทำไมต้องเริ่มต้นค่าในมุมมองแทนที่จะอยู่ในคอนโทรลเลอร์ของคุณ ฉันคิดว่าคุณรู้อยู่แล้วว่านั่นไม่ใช่วิธีการเริ่มต้นค่าทั่วไป (มิฉะนั้นคุณจะไม่ถาม) และคนอื่น ๆ จะสามารถให้คำตอบที่ดีกว่าหากพวกเขาเข้าใจกรณีการใช้งานของคุณดีขึ้น
Sean the Bean

1
@SeantheBean ฉันยังเด็กและโง่เขลา ... ;) ฉันไม่รู้ว่าทำไมฉันต้องทำ ฉันอาจจะพยายามแฮ็กอะไรบางอย่าง
Nix

คำตอบ:


139

ng-initไม่ทำงานเมื่อคุณกำหนดตัวแปรภายในลูป ใช้ {{myVariable=whatever;""}}

การต่อท้าย""จะหยุดนิพจน์เชิงมุมที่ถูกประเมินเป็นข้อความใด ๆ

จากนั้นคุณสามารถเรียก{{myVariable}}ให้แสดงค่าตัวแปรของคุณได้

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


1
แม้ว่าจะใช้งานได้ แต่ดูเหมือนแฮ็ค นั่นคือโดยทั่วไปเป็นแนวทางปฏิบัติที่ดีที่จะใช้{{}}สำหรับการแสดงผลตัวแปรเดียวเท่านั้นไม่ใช่เพื่อกำหนดตัวแปร ฉันจะบอกว่าstackoverflow.com/a/16799763/814160ถูกต้องมากกว่า (มีรหัส JS น้อยกว่าในมุมมอง)
Sean the Bean

1
+1 สำหรับ @SeantheBean - ฉันได้ทดสอบสิ่งนี้แล้ว ดูเหมือนว่าจะมีปัญหากับตัวควบคุมลูกและขอบเขตของการกำหนดตัวแปรในมาร์กอัป คำสั่งใช้งานได้ตามวัตถุประสงค์ของฉันและดูเหมือนจะเป็นวิธีแก้ปัญหาที่มั่นคง
Paul Carlton

2
ดูเหมือนจะใช้ไม่ได้ใน angular2/4 - การผูกไม่สามารถมีการกำหนดได้
Demodave

1
@Demodave คุณควรตั้งค่าตัวแปรคอนโทรลเลอร์ทั้งหมดของคุณในโค้ด typescript แทนและใช้เทมเพลตเพื่อเชื่อมต่อ typescript กับ HTML เท่านั้น เทมเพลตไม่ควรกำหนดตัวแปร
boxmein

81

ngInit สามารถช่วยในการเริ่มต้นตัวแปร

<div ng-app='app'>
    <div ng-controller="MyController" ng-init="myVar='test'">
        {{myVar}}
    </div>
</div>

ตัวอย่าง jsfiddle


3
ควรสังเกตว่าพวกเขาไม่แนะนำโซลูชันนี้สำหรับแอปจริง (แต่ไม่แนะนำทางเลือกอื่นจริงๆ): docs.angularjs.org/guide/dev_guide.mvc.understand_model
Mike Robinson

อย่างไรก็ตามสิ่งนี้ใช้ได้ผลสำหรับฉันในตอนแรกตัวแปรยังไม่ได้กำหนดไว้ในคอนโทรลเลอร์ ฉันสร้างวงรอบช่วงเวลาเล็กน้อย: var interval = setInterval (function () {if ($ scope.whatever) {// dostuff clearInterval (interval);}}, 10);
roelleor

19

สร้างคำสั่งที่เรียกmyVarด้วย

scope : { myVar: '@' }

และเรียกแบบนี้ว่า

<div name="my_map" my-var="Richmond,VA">

โดยเฉพาะอย่างยิ่งการอ้างอิงกรณีอูฐในคำสั่งไปยังชื่อแท็กยัติภังค์

สำหรับข้อมูลเพิ่มเติมโปรดดู "การทำความเข้าใจการเปลี่ยนและขอบเขต" ที่นี่: - http://docs.angularjs.org/guide/directive

นี่คือ Fiddleที่แสดงวิธีการคัดลอกค่าจากแอตทริบิวต์ไปยังตัวแปรขอบเขตในรูปแบบต่างๆภายในคำสั่ง


var-nick='my' var-nick2='test'ฉันต้องการที่จะสามารถที่จะทำหลายคน ถ้าคุณไม่สามารถคิดวิธีที่จะนำไปใช้กับคำสั่งฉันจะใช้ng-init
Nix

คุณสามารถรวมแอตทริบิวต์หลายรายการในขอบเขตได้สิ่งที่คุณต้องมีคือให้หนึ่งในนั้นเป็นชื่อของคำสั่งที่คุณต้องการดำเนินการ (หรือรวมชื่อคำสั่งนั้นไว้ใน html ด้วย) scope: {varNick: '@', varNick2: '@'}
Ian Mercer

แต่มันไม่สามารถปรับขนาดได้? ฉันจะต้องกำหนดคำสั่งต่อตัวแปร?
Nix

ไม่คุณไม่ต้องการคำสั่งต่อตัวแปร ลองดูซอที่ฉันเพิ่มลงในคำตอบ
Ian Mercer

ขออภัยฉันอ่านพลาดตัวอย่างของคุณสมบูรณ์แบบการเปลี่ยนแปลงเพียงอย่างเดียวของฉันคือขอบเขต {'@': '@ "}
Nix

10

คุณสามารถกำหนดค่าจาก html เช่นนี้ ฉันไม่คิดว่าจะมีวิธีแก้ปัญหาโดยตรงจากเชิงมุม

 <div style="visibility: hidden;">{{activeTitle='home'}}</div>

7
แฮ็คที่ดี ... ขอแนะนำ<div style="display: none">อย่างไรก็ตาม
Roger

3

คุณสามารถใช้ได้ng-initตามที่แสดงด้านล่าง

<div class="TotalForm">
  <label>B/W Print Total</label>
  <div ng-init="{{BWCount=(oMachineAccounts|sumByKey:'BWCOUNT')}}">{{BWCount}}</div>
</div>
<div class="TotalForm">
  <label>Color Print Total</label>
  <div ng-init="{{ColorCount=(oMachineAccounts|sumByKey:'COLORCOUNT')}}">{{ColorCount}}</div>
</div>

จากนั้นใช้ตัวแปรขอบเขตโลคัลในส่วนอื่น ๆ :

<div>Total: BW: {{BWCount}}</div>
<div>Total: COLOR: {{ColorCount}}</div>

ฉันชอบแนวทางนี้ ดูเหมือนแฮ็คน้อยกว่า อย่างไรก็ตามการชี้แจงอย่างหนึ่ง ng-init ไม่จำเป็นต้องใช้วงเล็บปีกกา
mklbtz

1
$scope.$watch('myVar', function (newValue, oldValue) {
        if (typeof (newValue) !== 'undefined') {
            $scope.someothervar= newValue;
//or get some data
            getData();
        }


    }, true);

ตัวแปรเริ่มต้นหลังจากตัวควบคุมดังนั้นคุณต้องเฝ้าระวังและเมื่อไม่ได้เริ่มต้นการใช้งาน


0

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

ดังนั้นใน globalController สร้าง

$scope.setScopeVariable = function(variable, value){
    $scope[variable] = value;
}

จากนั้นในไฟล์ html ของคุณเรียกมันว่า

{{setScopeVariable('myVar', 'whatever')}}

จากนั้นจะอนุญาตให้คุณใช้ $ scope.myVar ในตัวควบคุมของคุณ


0

หากคุณไม่อยู่ในวงคุณสามารถใช้ ng-init อื่นที่คุณสามารถใช้ได้

{{var=foo;""}}

เครื่องหมาย "" ไม่แสดงตัวแปรของคุณ


0

คุณสามารถใช้คำสั่ง ng-value ในช่องที่ซ่อนอยู่ด้านล่าง: -

<input type="hidden" ng-value="myScopeVar = someValue"/>

ซึ่งจะตั้งค่าของตัวแปรขอบเขต (myScopeVar) เป็น "someValue"

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