问题
My code:
breeze.config.initializeAdapterInstance("ajax", "angular", true);
...
var ajaxAdapter = breeze.config.getAdapterInstance('ajax');
ajaxAdapter.defaultSettings = {
method: 'POST',
data: {
CompanyName: 'Hilo Hattie',
ContactName: 'Donald',
City: 'Duck',
Country: 'USA',
Phone: '808-234-5678'
}
};
in line 14813 of breeze.debug.js:
ngConfig = core.extend(compositeConfig, ngConfig);
compositeConfig.method has a value of 'POST' until it is overwritten, because ngConfig.method has a value of 'GET'.
I imagine this question is relevant for any ajax setting, but of course I'm mainly struggling with how to post with the angular ajax adapter, so maybe there's an entirely better way to do that? this approach feels dirty anyway, but breeze.ajaxPost.js only works with the jQuery ajax adapter, right?
回答1:
6 Oct 2014 update
We recently had reason to revisit ajaxpost and have updated both the code and the documentation.
The original recommendation works. We're merely clarifying and updating the happy path.
A few points:
The ajaxpost plug-in works for both jQuery and Angular ajax adapters.
Those adapters long ago became aware of
adapter.defaultSettings.headers
and have blended them into your Breeze ajaxpost http calls (take heed, PW Kad).You must call
breeze.ajaxPost()
explicitly after replacing the default ajax adapter as you do when you use the 'breeze.angular' service.You can wrap a particular ajax adapter explicitly:
breeze.ajaxPost(myAjaxAdapter);
We just don't do that ourselves because, in our experience, it is sufficient to omit the params (breeze.ajaxPost()
) and let the method find-and-wrap whatever is the active ajax adapter of the moment.
The documentation explains the Angular use case which I repeat here to spare you some time:
// app module definition
var app = angular.module('app', ['breeze.angular']); // add other dependencies
// this data service abstraction definition function injects the 'breeze.angular' service
// which configures breeze for angular use including choosing $http as the ajax adapter
app.factory('datacontext', ['breeze', function (breeze) { // probably inject other stuff too
breeze.ajaxPost(); // wraps the now-current $http adapter
//... your service logic
}]);
Original reply
AHA! Thanks for the plunker (and the clever use of the Todo-Angular sample's reset method!).
In brief, the actual problem is that breeze.ajaxpost.js extends the jQuery ajax adapter, not the angular ajax adapter. There is a timing problem.
The root cause is that you can't tell breeze.ajaxpost.js which adapter to wrap. It always wraps the default adapter at the time that it runs. As you've got your script loading now, the jQuery adapter is the current one when breeze.ajaxpost.js runs.
The workaround is to set the default adapter to the angular adapter before breeze.ajaxpost.js runs.
One way to do that is to load the scripts as follows ... adding an inline script to set the default ajax adapter to the "angular" version.
<script src="breeze.debug.js"></script> <script> <!-- Establish that we will use the angular ajax adapter BEFORE breeze.ajaxpost.js wraps it! --> breeze.config.initializeAdapterInstance("ajax", "angular", true); </script> <script src="breeze.ajaxpost.js"></script>
Clearly this is a hack. We'll look into how we can change breeze.ajaxpost.js so you can wrap any ajax adapter at the time of your convenience.
回答2:
Thanks for finding this issue, and thanks Ward for bringing it to my attention. I've updated the breeze.ajaxpost.js code to use .data
as you described, and added a function you can call after adapter initialization. So now you can do:
var ajaxAdapter = breeze.config.initializeAdapterInstance("ajax", "angular");
ajaxAdapter.setHttp($http);
breeze.ajaxpost.configAjaxAdapter(ajaxAdapter); // now we can use POST
So, it's slightly less hacky.
回答3:
This answer is applicable to the following plugins and version:
Breeze.Angular v.0.8.7
Breeze.AjaxPost v.1.0.6
I just saw a new plugin called Breeze.Angular.js that can work in conjunction with Breeze.AjaxPost.js
You have to modify the Breeze.AjaxPost.js in order for it to work. Breeze.Angular.js initializes your adapter when your page loads, and Breeze.AjaxPost.js will take in the adapter initialized from Breeze.Angular.js
You can learn more about the Breeze.Angular server here: breeze-angular-service
You can learn more about Breeze.Ajaxpost here: breeze-ajaxpost
Now to set this up wasn't exactly apparent, because I took both files exactly as they were in git.
1.) Reference the files in this order:
<script src="Scripts/q.min.js"></script> <script src="Scripts/breeze.angular.js"></script> <script src="Scripts/breeze.ajaxpost.js"></script>
2.) Go into your breeze.ajaxpost.js
Remove this line (or comment this line):
breeze.ajaxpost(); // run it immediately on whatever is the current ajax adapter
The reason why is because, this will cause your ajaxpost method to run before your breeze.angular service. When you go into the ajaxpost method, the ajaxAdapter parameter that is supposed to be passed in will be null. Removing this line appends the functionality for later in your code, so you can call it from the breeze.angular service.
3.) In breeze.angular.js go to your useNgHttp method. It should look like this:
// configure breeze to use Angular's $http ajax adapter
var ajaxAdapter = breeze.config.initializeAdapterInstance("ajax", "angular");
ajaxAdapter.setHttp($http);
breeze.ajaxpost(ajaxAdapter); // now we can use POST
When you run your program, both plugins should be able to set up the environment for you without having to include it in every javascript that makes your calls to the webapi.
Thanks guys for the plugins.
来源:https://stackoverflow.com/questions/21268636/breeze-1-4-8-angular-ajax-adapter-how-to-customize-ajax-settings