在这里,我们将给大家分享关于Swift-如何在Firebase中使用“shouldChangeTextInRange”进行实时搜索?的知识,让您更了解swiftmessages的本质,同时也会涉及到如
在这里,我们将给大家分享关于Swift-如何在Firebase中使用“ shouldChangeTextInRange”进行实时搜索?的知识,让您更了解swiftmessages的本质,同时也会涉及到如何更有效地action="#{languageFrom.showChoice}": Target Unreachable, identifier 'languageFrom' resolved to null、android – 如何在Firebase Firestore中使用Query、android.widget.RatingBar.OnRatingBarChangeListener的实例源码、Angular jasmine fixture.detectChanges 如何触发 directive 的 set 方法的内容。
本文目录一览:- Swift-如何在Firebase中使用“ shouldChangeTextInRange”进行实时搜索?(swiftmessages)
- action="#{languageFrom.showChoice}": Target Unreachable, identifier 'languageFrom' resolved to null
- android – 如何在Firebase Firestore中使用Query
- android.widget.RatingBar.OnRatingBarChangeListener的实例源码
- Angular jasmine fixture.detectChanges 如何触发 directive 的 set 方法
Swift-如何在Firebase中使用“ shouldChangeTextInRange”进行实时搜索?(swiftmessages)
我想知道如何创建 Firebase匹配Regsexex查询 并使用 shouldChangeTextInRange 列出当前结果 。
我之前在Parse中做到了,它用于在Parse Cloud中搜索用户名或用户全名。如果有人阐明了我在Firebase中执行此操作的方法,那将是很棒的。
// search updatedfunc searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { // find by username let usernameQuery = PFQuery(className: "_User") usernameQuery.whereKey("username", matchesRegex: "(?i)" + searchBar.text!) usernameQuery.findObjectsInBackgroundWithBlock { (objects:[PFObject]?, error:NSError?) -> Void in if error == nil { // if no objects are found according to entered text in username column, find by fullname if objects!.isEmpty { let fullnameQuery = PFUser.query() fullnameQuery?.whereKey("fullname", matchesRegex: "(?i)" + self.searchBar.text!) fullnameQuery?.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in if error == nil { // clean up self.usernameArray.removeAll(keepCapacity: false) self.avaArray.removeAll(keepCapacity: false) // found related objects for object in objects! { self.usernameArray.append(object.objectForKey("username") as! String) self.avaArray.append(object.objectForKey("avatar") as! PFFile) } // reload self.tableView.reloadData() } }) } } // clean up self.usernameArray.removeAll(keepCapacity: false) self.avaArray.removeAll(keepCapacity: false) // found related objects for object in objects! { self.usernameArray.append(object.objectForKey("username") as! String) self.avaArray.append(object.objectForKey("avatar") as! PFFile) } // reload self.tableView.reloadData() } return true}
更新1:
我不能使用相同的父名称来完成它,snap.value并没有给我响应,甚至没有编译。因此,我尝试像这样做两个单独的父节点:firebase屏幕截图链接
我在xcode控制台上收到 每个笔画 first_name子节点的 indexOn安全警告 : __
[Firebase] 使用未指定的索引。考虑将/ people_spell上的“ .indexOn”:“ first_name /
T”添加到安全规则中,以获得更好的性能[Firebase] 使用未指定的索引。考虑将/ people_spell中的“ .indexOn”:“ first_name /
Te”添加到您的安全规则中,以获得更好的性能…更多次
我尝试过这些安全规则, 但并不能解决这些问题。它不包含每个子节点。我该如何提供?
"people_spell": { ".read": "auth !== null", ".write": "auth !== null", ".indexOn": "first_name" },"people": { ".read": "auth !== null", ".write": "auth !== null", ".indexOn": "first_name"}
我正在使用以下代码行:
let peopleSpellRef = Firebase(url: "https://sampleproject.firebaseio.com/people_spell")let peopleRef = Firebase(url: "https://sampleproject.firebaseio.com/people")func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { self.usernameArray.removeAll(keepCapacity: false) peopleSpellRef.queryOrderedByChild("first_name/\(searchBar.text!)").queryEqualToValue(true) .observeEventType(.Value, withBlock: { snapshot in let enumerator = snapshot.children while let rest = enumerator.nextObject() as? FDataSnapshot { peopleRef.childByAppendingPath("\(rest.key)").observeEventType(.Value, withBlock: { snapshot in self.usernameArray.removeAll(keepCapacity: false) let str: String = (snapshot.value.objectForKey("first_name")) as! (String) print(str) self.usernameArray.append(str) self.userkeyArray.append(snapshot.key) self.tableView.reloadData() }) } self.usernameArray.removeAll(keepCapacity: false) self.tableView.reloadData() })return true}
答案1
小编典典这不是Firebase的工作方式,您不能直接在Firebase中对子字符串进行“实时搜索”。但是,您可以格式化要搜索的Firebase数据,还有其他两种方法也可以实现目标。
一个很简单:将数据从Firebase加载到数组中,然后通过该数组进行NSPredicate搜索(或其他方法)。
另一个是查询完整字符串很容易。只要将文本分成要搜索的块:
people person_0 first_name: "Ted" last_name: "Stryker" position: "sitting down and facing front" person_1 first_name: "Teddy"
您可以在first_name中搜索“ Ted”,或在last_name中搜索“ Stryker”,但不能在位置搜索“ front”。
现在,解决方法和要记住的磁盘空间很便宜。
可以创建一个节点,使您可以通过多种方式搜索内容
people person_0 first_name //First name is Ted from above T: true Te: true Ted: true ed: true d: true e: true person_1 first_name //First name is Teddy from above T: true Te: true Ted: true etc
通过这种结构,我们可以找到所有以Ted开头的名字
peopleRef.queryOrderedByChild("first_name/Ted").queryEqualToValue(true) .observeEventType(.Value, withBlock: { snapshot in for child in snapshot.children { print(child.value) } })
可以执行其他搜索;搜索所有包含e或Te等的名字。
如果纯粹是这种情况,您正在搜索以在文本字段中执行自动填充(例如),则按击键一次对firebase进行ping操作将无法正常工作。
将Firebase中的数据加载到数组或字典(或其他内容)中可能是最好的解决方案。
action="#{languageFrom.showChoice}": Target Unreachable, identifier 'languageFrom' resolved to null
import javax.faces.bean.ManagedBean; //记得不是import javax.annotation.ManagedBean; @ManagedBean public class LanguageForm { private String language ; public String getLanguage() { return language; } public void setLanguage(String language) { this.language = language.trim() ; } public String showChoice() { if (isMissing(language)) { return "missing-language" ; } else if (language.equalsIgnoreCase("Java") || language.equalsIgnoreCase("Groovy")) { return "good-language" ; } else { return "bad-language" ; } } private boolean isMissing(String value) { return (value == null) || value.trim().isEmpty() ; } }
android – 如何在Firebase Firestore中使用Query
我正在使用Firebase功能和Firebase Firestore来开发用于存储用户数据的API.
我想使用存储在其字段中的属性来查找文档. This是Firebase文档,其中说明了如何实现相同目标.
// Create a reference to the cities collection
var citiesRef = db.collection('cities');
// Create a query against the collection
var queryRef = citiesRef.where('state', '==', 'CA');
我想处理两种情况
>没有符合现状的文件
>当前条件超过两份的文件
如何处理上述两种情况?
解决方法:
按照上面评论中的“讨论”,在@R_301_6221@中,您可以使用get()
方法返回的QuerySnapshot
执行以下操作:
admin.firestore().collection("cities")
.where('state', '==', 'CA')
.get()
.then(querySnapshot => {
if (querySnapshot.size == 0) {
console.log("0 documents");
} else if (querySnapshot.size > 2) {
console.log("More than 2 documents");
}
});
如上所述,请注意,这将花费集合中每个文档的读取.如果您有一个非常大的集合,您可以编写一个Cloud Function,每次在集合中添加/删除文档时更新计数器.
android.widget.RatingBar.OnRatingBarChangeListener的实例源码
@Hide @Override public void _initialize(final BA ba,Object activityClass,String EventName) { final ratingBar rb = new ratingBar(ba.context); final String eventName = EventName.toLowerCase(BA.cul); setobject(rb); innerInitialize(ba,eventName,true); if (ba.subExists(eventName + "_valuechanged")) { getobject().setonratingBarchangelistener(new OnratingBarchangelistener() { @Override public void onratingChanged(ratingBar ratingBar,float rating,boolean fromUser) { ba.raiseEventFromUI(rb,eventName + "_valuechanged",rating,fromUser); } }); } }
private void enableratingBar() { wordDifficultyrating.setEnabled(true); wordDifficultyrating .setonratingBarchangelistener(new OnratingBarchangelistener() { public void onratingChanged(ratingBar ratingBar,boolean fromUser) { difficultyRated = false; if (rating > 0.0f) { difficultyRated = true; } checkSubmitCondition(); } }); }
public void onGameInit() { submitrating = (Button) findViewById(R.id.submitratingButton); continueButton = (Button) findViewById(R.id.continueButton); wordInEnglish = (TextView) findViewById(R.id.wordInEnglish); translationLanguageTitle = (TextView) findViewById(R.id.translationTitle); translationToRate = (TextView) findViewById(R.id.translationToRate); translationratingBar = (ratingBar) findViewById(R.id.translationratingBar); languageOfTranslation = chooseRandomProficientLanguage(); this.setChangeableTextViews(); translationratingBar .setonratingBarchangelistener(new OnratingBarchangelistener() { public void onratingChanged(ratingBar ratingBar,boolean fromUser) { translationRated = false; if (rating > 0.0f) { translationRated = true; } checkSubmitCondition(); } }); submitrating.setVisibility(View.VISIBLE); continueButton.setVisibility(View.INVISIBLE); }
private void addListenerOnFoodQualityratingBar() { //if rating is changed,//store the current rating value in the result (float) automatically foodQualityratingBar.setonratingBarchangelistener(new OnratingBarchangelistener() { public void onratingChanged(ratingBar ratingBar,boolean fromUser) { setFoodQualityrating((double) rating); } }); }
private void addListenerOnValueForMoneyratingBar() { //if rating is changed,//store the current rating value in the result (float) automatically valueForMoneyratingBar.setonratingBarchangelistener(new OnratingBarchangelistener() { public void onratingChanged(ratingBar ratingBar,boolean fromUser) { setValueForMoneyrating((double) rating); } }); }
private void addListenerOnFoodPresentationratingBar() { //if rating is changed,//store the current rating value in the result (float) automatically foodPresentationratingBar.setonratingBarchangelistener(new OnratingBarchangelistener() { public void onratingChanged(ratingBar ratingBar,boolean fromUser) { setFoodPresentationrating((double) rating); } }); }
@Override public boolean convert(ItemBuilder builder,final ViewGroup parent,Float data) { builder.setrating(R.id.rating_bar,data).setStepSize(R.id.rating_bar,0.5f); builder.setonratingBarchangelistener(R.id.rating_bar,new OnratingBarchangelistener() { @Override public void onratingChanged(ratingBar ratingBar,boolean fromUser) { Toast.makeText(parent.getContext(),"rating is " + rating,Toast.LENGTH_SHORT).show(); } }); return true; }
private void initListener() { sobot_out_side_id.setonClickListener(new OnClickListener() { @Override public void onClick(View v) { KeyboardUtil.hideKeyboard(sobot_out_side_id); } }); sobot_ratingBar .setonratingBarchangelistener(new OnratingBarchangelistener() { @Override public void onratingChanged(ratingBar arg0,float arg1,boolean arg2) { score = sobot_ratingBar.getrating(); if (0 < score && score < 5) { hideLayout.setVisibility(View.VISIBLE); sobot_button_style.setVisibility(View.GONE); } else { hideLayout.setVisibility(View.GONE); comment("1",score + "","",0); } } }); btnCancle.setonClickListener(this); btnSubmit.setonClickListener(this); sobot_btn_no_robot.setonClickListener(this); sobot_btn_ok_robot.setonClickListener(this); sobot_close_Now.setonClickListener(this); gv_demo.setonItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent,View view,int position,long id) { TextView text = (TextView) view.findViewById(getResId("sobot_every_case")); Boolean isChecked = (Boolean) text.getTag(); if (!isChecked) { text.setTextColor(getResources().getColor(ResourceUtils.getIdByName(getApplicationContext(),"color","sobot_color_evaluate_text_pressed"))); text.setBackgroundResource(getResDrawableId("sobot_login_edit_pressed")); listChecked.add(text.getText().toString()); } else { text.setTextColor(getResources().getColor(ResourceUtils.getIdByName(getApplicationContext(),"sobot_color_evaluate_text_normal"))); text.setBackgroundResource(getResDrawableId("sobot_login_edit_nomal")); listChecked.remove(text.getText().toString()); } text.setTag(!isChecked); } }); }
/** * @see ratingBar#setonratingBarchangelistener(OnratingBarchangelistener) */ public W setonratingBarchangelistener(OnratingBarchangelistener listener) { mView.setonratingBarchangelistener(listener); return (W) this; }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); db = new CardDatabase(this); setContentView(R.layout.rate_card_view); Intent intent = getIntent(); Long cardId = intent.getExtras().getLong(CARD_rating_INTENT_ID_KEY); card = db.getCard(cardId); FrameLayout cardFrame = (FrameLayout) findViewById(R.id.CardFrame); TextView cardTitle = (TextView) findViewById(R.id.RateCardTitle); ratingBar rateCard = (ratingBar) findViewById(R.id.RateCardratingBar); rateCard.setrating(1f); rating = 1; Button doneBtn = (Button) findViewById(R.id.DoneratingButton); textSideViewer = new TextView(this); imgSideViewer = new ImageView(this); final RateCardActivity self = this; if (card != null) { cardTitle.setText(card.getTitle()); if (card.getSide2Type() == Card.TEXT_TYPE) { textSideViewer.setText(card.getSide2Text()); cardFrame.addView(textSideViewer); } else { imgSideViewer.setimageURI(card.getSide2URI()); cardFrame.addView(imgSideViewer); } OnratingBarchangelistener ratingListener = new OnratingBarchangelistener() { public void onratingChanged(ratingBar arg0,float ratingFloat,boolean arg2) { rating = Math.round(ratingFloat); L.d("onratingChanged","rating is Now %d from float: %f",ratingFloat); } }; OnClickListener doneListener = new OnClickListener() { public void onClick(View v) { card.incrementCount(); SM2.scoreCardAndCalculateInterval(card,rating); L.d("onClick doneListener","Cards ef after: %f",card.getEFactor()); card.setLastTime(new Date().getTime()); db.upsertCard(card); self.setResult(QuizActivity.CARD_rating_RESULT); self.finish(); } }; doneBtn.setonClickListener(doneListener); rateCard.setonratingBarchangelistener(ratingListener); } else { // Show an error message } }
/** * This method is called when the {@link Activity} is started. It is responsible for the * initialization of the fields. It also sets an {@link OnratingBarchangelistener} for the * {@link ratingBar} and the <code>spinnerLongClick</code> on the field <code>spinner_markComment</code>. * * The method also shows the information {@link Toast} for the user. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_grade); prefs = getSharedPreferences(C.prefs.FILE_NAME,MODE_PRIVATE); textView_studentName = (TextView) findViewById(R.id.textView_studentName); spinner_markType = (Spinner) findViewById(R.id.spinner_markType); ratingBar_markrating = (ratingBar) findViewById(R.id.ratingBar_markrating); spinner_markComment = (Spinner) findViewById(R.id.spinner_markComment); textView_bottomInfo = (TextView) findViewById(R.id.textView_bottomInfo); ratingBar_markrating.setonratingBarchangelistener(new OnratingBarchangelistener() { /** * This method makes sure that the ratingBar never has a rating lower than 1 and bigger than 5. */ @Override public void onratingChanged(ratingBar ratingBar,boolean fromUser) { if(rating<1) { ratingBar.setrating(1); }else if(rating>5) { ratingBar.setrating(5); } } }); spinner_markComment.setonLongClickListener(spinnerLongClick); textView_studentName.setText(getIntent().getExtras().getString( C.intent.bundle.STUDENTNAME)); activeClass = prefs.getString(C.prefs.ACTIVE_CLASS,getString(R.string.nodata)).toupperCase(); activeSubject = prefs.getString(C.prefs.ACTIVE_SUBJECT,getString(R.string.nodata)).toupperCase(); textView_bottomInfo.setText(activeSubject+"/"+activeClass); if(SHOW_COMMENT_SPINNER_INFO) { Toast.makeText(getApplicationContext(),R.string.toast_addCommentInfo,Toast.LENGTH_SHORT).show(); SHOW_COMMENT_SPINNER_INFO = false; } }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_rating); utilhelper = new Util_Database(this); UserID = utilhelper.getUSER_ID(); Intent intent = getIntent(); PID = intent.getStringExtra(Post_Fragment.PostID); rating_btn = (Button) findViewById(R.id.rating_btn); rate_progressBar = (ProgressBar) findViewById(R.id.rate_progressBar); rate_progressBar.setVisibility(View.GONE); RateCount=(TextView)findViewById(R.id.rate_count); RateBar=(ratingBar)findViewById(R.id.main_ratingbar); RateBar.setonratingBarchangelistener(new OnratingBarchangelistener() { /*public void OnratingBarChanged(ratingBar ratingBar,boolean fromUser){ RateCount.setText(String.valueOf(rating)+"/5.0"); }*/ @Override public void onratingChanged(ratingBar ratingBar,boolean fromUser) { RateCount.setText(String.valueOf(rating)+"/5.0"); } }); }
Angular jasmine fixture.detectChanges 如何触发 directive 的 set 方法
测试代码:
import { Component } from ''@angular/core'';
import { waitForAsync, ComponentFixture, TestBed } from ''@angular/core/testing'';
import { FocusDirective } from ''./focus.directive'';
import { KeyboardFocusService } from ''./services'';
import { By } from ''@angular/platform-browser'';
@Component({
selector: ''cx-host'',
template: ` <div id="b" [cxFocus]="{autofocus: '':host''}" [cxRefreshFocusOn]="jerry"></div> `,
})
class MockComponent {
jerry = 1;
}
class MockKeyboardFocusService {
get() {}
set() {}
shouldFocus() {}
getPersistenceGroup() {}
findFirstFocusable(){}
hasPersistedFocus(){}
}
describe(''FocusDirective'', () => {
let fixture: ComponentFixture<MockComponent>;
let component: MockComponent;
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [FocusDirective, MockComponent],
providers: [
{
provide: KeyboardFocusService,
useClass: MockKeyboardFocusService,
},
],
}).compileComponents();
fixture = TestBed.createComponent(MockComponent);
component = fixture.componentInstance;
fixture.detectChanges();
})
);
it(''should focus itself'', () => {
let service: KeyboardFocusService;
service = TestBed.inject(KeyboardFocusService);
const host = fixture.debugElement.query(By.css(''#b''));
const el = host.nativeElement;
spyOn(service, ''findFirstFocusable'').and.returnValue(el);
spyOn(el, ''focus'').and.callThrough();
fixture.detectChanges();
const event = {
preventDefault: () => {},
stopPropagation: () => {},
};
host.triggerEventHandler(''focus'', event);
expect(el.focus).toHaveBeenCalled();
expect(service.findFirstFocusable).toHaveBeenCalled();
component.jerry = 2;
fixture.detectChanges();
});
});
在单元测试代码里显式修改 Component 的 jerry 属性为 2:
detectChanges 会触发 ngZone 的 run 方法,进而调用_tick 函数:
以 callback 的方式回调_tick ():
changeDetectorRef 指向 RootViewRef, 因此执行 Root view 的 change detection 策略:
最后执行到 refreshView 里的 executeTemplate 方法:
执行 template function:
待更新 template 的属性名称:cxRefreshFocusOn, 属性值:2
function elementPropertyInternal(tView, tNode, lView, propName, value, renderer, sanitizer, nativeOnly) {
ngDevMode && assertNotSame(value, NO_CHANGE, ''Incoming value should never be NO_CHANGE.'');
const element = getNativeByTNode(tNode, lView);
let inputData = tNode.inputs;
let dataValue;
if (!nativeOnly && inputData != null && (dataValue = inputData[propName])) {
setInputsForProperty(tView, lView, dataValue, propName, value);
if (isComponentHost(tNode))
markDirtyIfOnPush(lView, tNode.index);
if (ngDevMode) {
setNgReflectProperties(lView, element, tNode.type, dataValue, value);
}
}
这个 33 是 element 在 LView 中的索引值:
从 lView 里根据索引值 33 拿到 directive 实例:
最后设置该实例的值为 2:
更多 Jerry 的原创文章,尽在:“汪子熙”:
本文同步分享在 博客 “汪子熙”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与 “OSC 源创计划”,欢迎正在阅读的你也加入,一起分享。
我们今天的关于Swift-如何在Firebase中使用“ shouldChangeTextInRange”进行实时搜索?和swiftmessages的分享已经告一段落,感谢您的关注,如果您想了解更多关于action="#{languageFrom.showChoice}": Target Unreachable, identifier 'languageFrom' resolved to null、android – 如何在Firebase Firestore中使用Query、android.widget.RatingBar.OnRatingBarChangeListener的实例源码、Angular jasmine fixture.detectChanges 如何触发 directive 的 set 方法的相关信息,请在本站查询。
本文标签: