好的,所以这很奇怪,我敢肯定对此有一个很好的解释,但这使我难以理解。基础知识:
LogGoals
函数中。ionic serve
之后首次加载该应用程序),该列表已成功保存。以下是有问题的提供者:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage';
@Injectable()
export class GoalproviderProvider {
public all_goals:any = [];
public viewed_tutorial = false;
public style_options = [
{
style_name: "girl-and-dog",
style_color: "#5bc3cc",
style_icon: "md-paw",
style_icon_color: "#FFFFFF",
mood: "Joyous"
},
{
style_name: "pink-city",
style_color: "#f7ced9",
style_icon: "md-radio",
style_icon_color: "#FFFFFF",
mood: "Serene"
},
{
style_name: "snow-guy",
style_color: "#b4cbb9",
style_icon: "md-snow",
style_icon_color: "#FFFFFF",
mood: "Confident"
},
{
style_name: "fish-shop",
style_color: "#31c1e9",
style_icon: "md-rainy",
style_icon_color: "#FFFFFF",
mood: "Relaxed"
}
];
constructor(public http: HttpClient,
private storage: Storage) {
console.log('Loading Goals');
this.LoadGoals();
}
public ClearAllData() {
this.storage.clear();
}
public GetWatchedGoals() {
var watched_goals = [];
var i = 0;
while(i < this.all_goals.length) {
var k = 0;
while(k < this.all_goals[i].goal_list.length) {
var child_watched_goals = this.GetWatchedGoalsRecursively(this.all_goals[i].goal_list[k]);
watched_goals = watched_goals.concat(child_watched_goals);
k++;
}
i++;
}
return watched_goals;
}
public GetWatchedGoalsRecursively(goal) {
var watched_goals = [];
if(goal.goal_watch && !goal.goal_complete && !goal.goal_deleted)
watched_goals.push(goal);
var i = 0;
while(i < goal.goal_list.length) {
var child_watched_goals = this.GetWatchedGoalsRecursively(goal.goal_list[i]);
watched_goals = watched_goals.concat(child_watched_goals);
i++;
}
return watched_goals;
}
public AppendAndReturnNewGoal(goal_style, goal_title) {
var new_goal = {
goal_style: goal_style,
goal_title: goal_title,
goal_list: [],
goal_id: new Date().getUTCMilliseconds()
};
this.all_goals.push(new_goal);
this.LogGoals();
return new_goal;
}
public EditGoalTitle(goal, new_title) {
goal.goal_title = new_title;
this.LogGoals();
}
public AddGoalChild(goal, new_title) {
var new_goal = {
goal_title: new_title,
goal_watch: false,
goal_complete: false,
goal_deleted: false,
goal_list: [],
goal_id: new Date().getUTCMilliseconds()
}
goal.goal_list.push(new_goal);
this.LogGoals();
}
public AddGoalParent(goal, new_title) {
var new_goal = {
goal_title: goal.goal_title,
goal_watch: goal.goal_watch,
goal_complete: goal.goal_complete,
goal_deleted: goal.goal_deleted,
goal_list: goal.goal_list,
goal_id: goal.goal_id
}
goal.goal_title = new_title;
goal.goal_watch = false;
goal.goal_complete = false;
goal.goal_deleted = false;
goal.goal_list = [ new_goal ];
goal.goal_id = new Date().getUTCMilliseconds();
this.LogGoals();
}
public DeleteGoal(goal) {
goal.goal_deleted = true;
this.LogGoals();
}
public ToggleGoalComplete(goal) {
goal.goal_complete = !goal.goal_complete;
this.LogGoals();
}
public ToggleGoalWatch(goal) {
goal.goal_watch = !goal.goal_watch;
this.LogGoals();
}
public UpdateMasterGoal(goal_id, new_goal) {
}
LogGoals() {
// TODO : I THINK WE HAVE TO TIMEOUT THIS FUNCTION TO ALLOW "ALL_GOALS" TO CATCH UP.
console.log('GOAL LOG:', this.all_goals);
this.storage.set('all_goals', this.all_goals);
}
LoadGoals() {
this.all_goals = [];
this.storage.get('all_goals').then((val) => {
if(!val) {
val = [];
this.storage.set('all_goals', val);
}
console.log('GOALS LOADED FROM STORAGE:', val);
this.all_goals = val;
});
}
}
在此代码段中,我有一个变量all_goals
。该变量与一系列递归组件相连,这些递归组件能够更新/操纵各自的目标。
组件:
import { Component } from '@angular/core';
import { Input } from '@angular/core';
import { ActionSheetController, AlertController } from 'ionic-angular';
import { GoalproviderProvider } from '../../providers/goalprovider/goalprovider';
import { MonetizationProvider } from '../../providers/monetization/monetization';
@Component({
selector: 'goalem-list',
templateUrl: 'goalem.html'
})
export class GoalemComponent {
@Input() goal_list;
@Input() search_term;
@Input() nested_level;
constructor(public actionSheetCtrl: ActionSheetController,
public alertCtrl: AlertController,
public goal_provider: GoalproviderProvider,
public monetization_provider: MonetizationProvider) {
}
PresentActionSheet(goal) {
const actionSheet = this.actionSheetCtrl.create({
title: goal.goal_title,
buttons: [
{
text: 'Add Step',
icon: 'add-circle',
handler: () => {
console.log('Add Child Step');
this.PresentAddChildPopup(goal);
}
},
{
text: 'Add Parent Step',
icon: 'add-circle',
handler: () => {
console.log('Add Parent Step');
this.PresentAddParentPopup(goal);
}
},
{
text: goal.goal_complete ? 'Mark Incomplete' : 'Mark Complete',
icon: goal.goal_complete ? 'close-circle' : 'checkmark-circle',
handler: () => {
console.log('Check Off');
this.goal_provider.ToggleGoalComplete(goal);
}
},
{
text: 'Edit',
icon: 'build',
handler: () => {
console.log('Edit Goal');
this.PresentEditPopup(goal);
}
},
{
text: goal.goal_watch ? 'Stop Watching' : 'Watch',
icon: goal.goal_watch ? 'eye-off' : 'eye',
handler: () => {
console.log('Watch Goal');
this.goal_provider.ToggleGoalWatch(goal);
}
},
{
text: 'Delete',
icon: 'trash',
role: 'destructive',
handler: () => {
console.log('Delete Goal');
this.PromptConfirmDelete(goal);
}
},
{
text: 'Cancel',
icon: 'close',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}
]
});
actionSheet.present();
}
PresentEditPopup(goal) {
const prompt = this.alertCtrl.create({
title: 'Edit Step',
message: "Enter a description for this step.",
inputs: [
{
name: 'title',
placeholder: 'Description...',
value: goal.goal_title
},
],
buttons: [
{
text: 'Cancel',
handler: data => {
console.log('Cancel clicked');
}
},
{
text: 'Submit',
handler: data => {
this.goal_provider.EditGoalTitle(goal, data.title);
}
}
]
});
prompt.present();
}
PresentAddChildPopup(goal) {
if(this.nested_level > 3) {
var limit_title = "It's goals all the way down, mate.";
var limit_description = "You've discovered a premium feature! To unlock your app's true potential, click the button below. Your donation helps cover our operating costs, allowing us to continue providing the fantastic service you deserve!";
if(this.monetization_provider.PromptUpgradeIfNotPremium(limit_title, limit_description))
return;
}
const prompt = this.alertCtrl.create({
title: 'Create Step',
message: "Enter a description for this step.",
inputs: [
{
name: 'title',
placeholder: 'Description...'
},
],
buttons: [
{
text: 'Cancel',
handler: data => {
console.log('Cancel clicked');
}
},
{
text: 'Submit',
handler: data => {
this.goal_provider.AddGoalChild(goal, data.title);
}
}
]
});
prompt.present();
}
PresentAddParentPopup(goal) {
const prompt = this.alertCtrl.create({
title: 'Create Step',
message: "Enter a description for this step.",
inputs: [
{
name: 'title',
placeholder: 'Description...'
},
],
buttons: [
{
text: 'Cancel',
handler: data => {
console.log('Cancel clicked');
}
},
{
text: 'Submit',
handler: data => {
this.goal_provider.AddGoalParent(goal, data.title);
}
}
]
});
prompt.present();
}
PromptConfirmDelete(goal) {
const confirm = this.alertCtrl.create({
title: 'Are You Sure?',
message: 'By deleting this step, you will also delete any children steps. This can not be undone. Continue?',
buttons: [
{
text: 'Cancel',
handler: () => {
console.log('Disagree clicked');
}
},
{
text: 'Okay',
handler: () => {
this.goal_provider.DeleteGoal(goal);
}
}
]
});
confirm.present();
}
}
<ul *ngIf="goal_list.length">
<li *ngFor="let goal of goal_list">
<ion-item class="goal-item" *ngIf="!goal.goal_deleted && (!search_term || goal.goal_title.toLowerCase().includes(search_term.toLowerCase()))">
<p [ngStyle]="{'text-decoration': goal.goal_complete ? 'line-through' : 'none'}">{{goal.goal_title}}</p>
<button ion-button clear item-end (tap)="PresentActionSheet(goal);">
<ion-icon name="md-menu"></ion-icon>
</button>
</ion-item>
<goalem-list [goal_list]="goal.goal_list" [search_term]="search_term" [nested_level]="nested_level + 1" *ngIf="goal.goal_list.length && !goal.goal_deleted"></goalem-list>
</li>
</ul>
您可以看到该组件自行调用。这将创建一系列嵌套的组件,以反映提供者的嵌套目标列表。
从功能上讲,除保存外,一切正常。到目前为止,这是我发现的东西:
all_goals
始终镜像目标树。每当我对目标树进行更新时,它都会“同步”回提供程序中的all_goals
变量。all_goals
。 all_goals从存储加载,然后永不更改。因此,无论何时将其保存到存储中,它都不会编写任何更新(因为变量未更新)。我有点困惑,这已经接近我的技能范围了,所以不确定如何进行调试。作为参考,下面是调用最根本的goal-list
组件的页面。
<ion-header>
<ion-navbar class="overlapping-navbar">
<button ion-button menuToggle icon-only>
<ion-icon name='menu'></ion-icon>
</button>
<ion-input [(ngModel)]="search_term" placeholder="Search..."></ion-input>
</ion-navbar>
</ion-header>
<ion-content scroll="false" [ngStyle]="{'background-color': goal_color}">
<div class="splash-bg">
<img [src]="goal_image" />
</div>
<div class="splash-info">
<!-- <div class="splash-logo"></div> -->
<div class="splash-goal">
<div>
{{goal_title}}
</div>
</div>
</div>
<div class="goal-list">
<goalem-list [goal_list]="goal_list" [search_term]="search_term" [nested_level]="1" *ngIf="goal_list"></goalem-list>
<button class="rpg-button" ion-button icon-end large (click)="PromptForNewGoal()"
style="margin:auto; display:block; margin-top:35px;">
Map It!
</button>
</div>
</ion-content>
如果有什么我想提供的更多信息,请告诉我:)我认为问题出在嵌套上,但令我困惑的是它有效。真奇怪...