2015-05-04 20 views
1

我有一個創建多個表單元素一個指令:指令模板內AJAX查詢

// Directive 
app.directive('comboInput', function(){ 
    return { 
     scope: { 
      imodel: '=', 
      dmodel: '=', 
      bmodel: '=', 
      inputname: '@', 
      integers: '=', 
      decimals: '=' 
     }, 
     templateUrl: templatePath + 'combo-input.html' 
    } 
}); 

// Template 
<select id="" ng-model="imodel" ng-change="bmodel=imodel+dmodel" ng-options="value for value in integers"></select> 
<select id="" ng-model="dmodel" ng-change="bmodel=imodel+dmodel" ng-options="(value|fraction) for value in decimals"></select> 
<input type="number" name="{{inputname}}" ng-model="bmodel"> 

// Usage 
<combo-input inputname="width" bmodel="width" imodel="widthI" dmodel="widthD" integers="ints" decimals="decs"></combo-input> 

此應用程序的控制器具有搶到了價格的方法:

$scope.getProductPrice = function(){ 
    return $http.post('/customize/angular/getProductPrice', { 
     sku: '$scope.sku', 
     width: $scope.width, 
     height: $scope.height 
    }).then(function(response){ 
     $scope.productPrice = parseFloat(response.data).toFixed(2); 
    }); 
} 

我用這個方法對各種零件通常通過在某個表單元素上調用ng-change="getProductPrice()";但是,從模板調用它時不起作用。

我已經嘗試了許多不同的答案,我在這裏找到了,但沒有一個按預期的方式工作(如無限$ http調用永遠運行),或者如果他們這樣做,提交答案的人提供沒有評論或其他細節爲什麼的代碼工作,所以我無法適應我的需求。最重要的是,各種方法都使用不同的技術,有些已被棄用,所以沒有一致性來確定我需要做什麼。

如何從我的指令模板中撥打getProductPrice()


編輯

我創建了一個Plunker證明舊值傳遞給getProductPrice()方法。

http://plnkr.co/edit/1nRs26nTaSOztjvVyLYg?p=preview

回答

1

您的指令具有隔離範圍(scope: {...}),所以它不會有進入上層控制範圍的變量和方法,如getProductPrice

你可以做的是通過這種方法作爲參數傳遞給你的指令:

app.directive('comboInput', function() { 
    return { 
    scope: { 
     imodel: '=', 
     dmodel: '=', 
     bmodel: '=', 
     inputname: '@', 
     integers: '=', 
     decimals: '=', 
     on-change: '&' 
    }, 
    templateUrl: templatePath + 'combo-input.html' 
    } 
}); 

然後您可以實例化這樣的:

<combo-input ... on-change="getProductPrice()"></combo-input> 

然後你只需要調用scope.onChange()從指令來調用已綁定到on-change屬性的此函數。

或者,你可以將它甚至直接綁定到內置ng-change

<input ... ng-change="onChange()"> 

UPDATE:如果你想傳遞的具體參數爲這個電話,你可以簡單地將它們添加方法簽名:

$scope.getProductPrice = function(width, height) { ... } 

而且也是在指令綁定:

<combo-input ... on-change="getProductPrice(width, height)"></combo-input> 

然後您需要做的就是使用這些參數調用onChange。如果你寫的是,在HTML,它是那樣簡單:

<input ng-change="onChange(width, height)"> 

(確保widthheight是在你的指令範圍明顯,因此它可以在HTML中使用)。

如果你想從代碼中調用,那麼widthheight已經在你的範圍內,在這種情況下,你只需要調用scope.onChange()。但是,如果他們沒有,你可以添加這些參數只是這個調用與此特定的語法:

scope.onChange({width: value1, height:value2}) 

另一種方法是使這一阿賈克斯方法的服務,而不是一個控制器功能。通過在您的指令中注入服務,您可以直接撥打myService.getProductPrice()。參數綁定的優點是可以重用指令的不同行爲,但如果它總是調用該函數,則優先選擇服務。

+0

我原以爲這應該是這麼簡單,我不明白爲什麼這麼多其他答案讓一切變得如此複雜;然而,在這個例子中,請求參數總是舊值而不是新值。 – pspahn

+0

究竟是什麼請求參數?它是''$ scope.sku「'?這在你的例子中似乎是一個常量字符串。 – floribon

+0

PS:你發現的複雜答案可能是直接綁定'$ http'調用給諸如「{{getProductPrice()}}」的觀察者(因此在每個摘要循環中執行)。這曾經被支持,但不再是通話正在進行(並且正在殺死服務器)。在你的情況下,你只在特定的事件('ng-change')執行調用,所以沒關係。 – floribon

0

由於您將您的指令的範圍聲明爲新範圍,因此您聲明的條目在此範圍與外部(使用您的方法)之間進行綁定。

您可以使用指令定義對象的作用域散列將函數傳遞給指令作用域,也可以使用指令中的相同控制器添加另一個ng-controller。