问题 简而言之,我的指令中有一个函数,它不会在执行前等待解析的承诺。
背景
我创建了一个使用selectContacts
服务的contactsAPI
指令。我已经在我的应用程序中使用了与其他控制器相同的contactsAPI
服务(所以我知道它有效),但这是我第一次尝试将其注入指令。当我的指令控制器调用contactsAPI.getContacts()
时,我希望.then()
函数在执行之前等待来自contactsAPI.getContacts()
的承诺解析,但似乎并非如此。相反,.then()
函数会立即触发,导致contacts
变量中的undefined
值被分配contactsAPI
。
这是我的app.service('contactsAPI', ['$rootScope', '$http', '$q', function($rootScope, $http, $q) {
var contactsAPI = this;
var contactsAPI.contacts = [];
contactsAPI.getContacts = function() {
var deferred = $q.defer();
if(!contactsAPI.contacts) {
$http.get('/contacts.json').then(function(resp) {
if(resp && resp.data) {
contactsAPI.contacts = resp.data.contacts;
deferred.resolve(contactsAPI.contacts);
} else {
deferred.resolve([]);
}
}, function(err) {
contactsAPI.error = true;
deferred.reject(err);
});
} else {
deferred.resolve(contactsAPI.contacts);
}
return deferred.promise;
};
}]);
:
selectContacts
这是我的app.directive('selectContacts', ['$http', 'modal', 'contactsAPI', function($http, modal, contactsAPI) {
return {
replace: true,
templateUrl: '/assets/select_contacts.html',
transclude: false,
scope: {
story: '=',
token: '@'
},
controller: ['$scope', '$http', 'modal', 'contactsAPI', function($scope, $http, modal, contactsAPI) {
var contacts;
contactsAPI.getContacts().then(function(resp){
contacts = contactsAPI.contacts;
});
}]
}
}]);
指令:
contactsAPI.contacts
我尝试了几种不同的方法来解决问题,但没有成功:
我尝试将观察者附加到contacts
并在我的指令中安装一个监听器。我的结果好坏参半。有时undefined
会被正确定义,但至少有一半的时间是contactsAPI.getContacts()
。
我尝试将我的contacts
getter函数从我的指令移动到其父控制器,然后将结果注入我的指令范围。失败是因为undefined
在实例化指令时仍然是$scope.contacts
。从一开始这种做法似乎是不好的做法,但值得一试。
我尝试了类似于上面#2的方法,除了我将联系人加载到指令的父控制器中,而不是在父控制器contactAPI.getContacts()
上附加了一个观察者。指令中的监听器。那也没有用,只是看起来很糟糕。
我三倍检查了我对该指令的依赖注入是否正确。我遇到的一些帖子中出现了类似的问题,这些问题是由于依赖项被错误地注入或者出现故障而导致的。
我还确保deferred
contactsAPI
变量在<model>
的生命期内不会持续存在,public partial class MyDbEntities : DbContext
{
public MyDbEntities()
: base("name=MyDbEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<User>().Property(u => u.Name).IsRequired().HasMaxLength(256);
modelBuilder.Entity<User>().Property(u => u.Surname).IsRequired().HasMaxLength(256);
modelBuilder.Entity<User>().Property(u => u.Email).IsRequired().HasMaxLength(200);
modelBuilder.Entity<User>().Property(u => u.password).IsRequired().HasMaxLength(100);
modelBuilder.Entity<User>().Property(u => u.address).IsRequired();
modelBuilder.Entity<User>().Property(u => u.postcode).IsRequired();
modelBuilder.Entity<User>().Property(u => u.number).IsRequired();
}
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.ErrorMessage));
throw new DbEntityValidationException(errorMessages);
}
}
public virtual DbSet<User> Users { get; set; }
}
是 [HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(User U)
{
using(MyDbEntities db=new MyDbEntities())
{
db.Users.Add(U);
db.SaveChanges();
ModelState.Clear();
U = null;
ViewBag.Message("Seccesfully stored");
}
return View(U);
}
的来源{3}}