问:
Alias properties in LINQ to SQL
I'm using a shim property to make sure that the date is always UTC. This in itself is pretty simple but now I want to query on the data. I don't want to expose the underlying property, instead I want queries to use the shim property. What I'm having trouble with is mapping the shim property. For example:

```<code>public partial class Activity
{
    public DateTime Started
    {
        // Started_ is defined in the DBML file
        get{ return Started_.ToUniversalTime(); }
        set{ Started_ = value.ToUniversalTime(); }
    }
}

var activities = from a in Repository.Of<Activity>()
                 where a.Started > DateTime.UtcNow.AddHours( - 3 )
                 select a;
</code>```

Attempting to execute the query results in an exception:

```<code>System.NotSupportedException: The member 'Activity.Started' has no supported
translation to SQL.
</code>```

This makes sense - how could LINQ to SQL know how to treat the Started property - it's not a column or association? But, I was looking for something like a ColumnAliasAttribute that tells SQL to treat properties of Started as Started_ (with underscore).

Is there a way to help LINQ to SQL translate the expression tree to the Started property can be used just like the Started_ property?

答:
Another example cannot hurt I guess.
In my Template class, I have a field Seconds that I convert to TimeStamp relatively to UTC time. This statement also has a CASE (a?b:c).

```<code>    private static readonly CompiledExpression<Template, DateTime> TimeStampExpression =
        DefaultTranslationOf<Template>.Property(e => e.TimeStamp).Is(template =>
            (template.StartPeriod == (int)StartPeriodEnum.Sliding) ? DateTime.UtcNow.AddSeconds(-template.Seconds ?? 0) :
            (template.StartPeriod == (int)StartPeriodEnum.Today) ? DateTime.UtcNow.Date :
            (template.StartPeriod == (int)StartPeriodEnum.ThisWeek) ? DateTime.UtcNow.Date.AddDays(-(int)DateTime.UtcNow.DayOfWeek) :   // Sunday = 0
            (template.StartPeriod == (int)StartPeriodEnum.ThisMonth) ? new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1, 0, 0, 0, DateTimeKind.Utc) :
            (template.StartPeriod == (int)StartPeriodEnum.ThisYear) ? new DateTime(DateTime.UtcNow.Year, 1, 1, 0, 0, 0, DateTimeKind.Utc) :
            DateTime.UtcNow     // no matches
        );

    public DateTime TimeStamp
    {
        get { return TimeStampExpression.Evaluate(this); }
    }
</code>```

My query to initialize a history-table based on (Event.TimeStamp >= Template.TimeStamp):

```<code>    foreach (var vgh in (from template in Templates
                        from machineGroup in MachineGroups
                        let q = (from event in Events
                                 join vg in MachineGroupings on event.MachineId equals vg.MachineId
                                 where vg.MachineGroupId == machineGroup.MachineGroupId
                                 where event.TimeStamp >= template.TimeStamp
                                 orderby (template.Highest ? event.Amount : event.EventId) descending
                                 select _makeMachineGroupHistory(event.EventId, template.TemplateId, machineGroup.MachineGroupId))
                        select q.Take(template.MaxResults)).WithTranslations())
        MachineGroupHistories.InsertAllOnSubmit(vgh);
</code>```

It takes a defined maximum number of events per group-template combination.

Anyway, this trick sped up the query by four times or so.

Title: Alias properties in LINQ to SQL

Body:
I'm using a shim property to make sure that the date is always UTC. This in itself is pretty simple but now I want to query on the data. I don't want to expose the underlying property, instead I want queries to use the shim property. What I'm having trouble with is mapping the shim property. For example:

public partial class Activity
{
    public DateTime Started
    {
        // Started_ is defined in the DBML file
        get{ return Started_.ToUniversalTime(); }
        set{ Started_ = value.ToUniversalTime(); }
    }
}

var activities = from a in Repository.Of<Activity>()
                 where a.Started > DateTime.UtcNow.AddHours( - 3 )
                 select a;

Attempting to execute the query results in an exception:

System.NotSupportedException: The member 'Activity.Started' has no supported
translation to SQL.

This makes sense - how could LINQ to SQL know how to treat the Started property - it's not a column or association? But, I was looking for something like a ColumnAliasAttribute that tells SQL to treat properties of Started as Started_ (with underscore).

Is there a way to help LINQ to SQL translate the expression tree to the Started property can be used just like the Started_ property?

Body:
Another example cannot hurt I guess.
In my Template class, I have a field Seconds that I convert to TimeStamp relatively to UTC time. This statement also has a CASE (a?b:c).

    private static readonly CompiledExpression<Template, DateTime> TimeStampExpression =
        DefaultTranslationOf<Template>.Property(e => e.TimeStamp).Is(template =>
            (template.StartPeriod == (int)StartPeriodEnum.Sliding) ? DateTime.UtcNow.AddSeconds(-template.Seconds ?? 0) :
            (template.StartPeriod == (int)StartPeriodEnum.Today) ? DateTime.UtcNow.Date :
            (template.StartPeriod == (int)StartPeriodEnum.ThisWeek) ? DateTime.UtcNow.Date.AddDays(-(int)DateTime.UtcNow.DayOfWeek) :   // Sunday = 0
            (template.StartPeriod == (int)StartPeriodEnum.ThisMonth) ? new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1, 0, 0, 0, DateTimeKind.Utc) :
            (template.StartPeriod == (int)StartPeriodEnum.ThisYear) ? new DateTime(DateTime.UtcNow.Year, 1, 1, 0, 0, 0, DateTimeKind.Utc) :
            DateTime.UtcNow     // no matches
        );

    public DateTime TimeStamp
    {
        get { return TimeStampExpression.Evaluate(this); }
    }

My query to initialize a history-table based on (Event.TimeStamp >= Template.TimeStamp):

    foreach (var vgh in (from template in Templates
                        from machineGroup in MachineGroups
                        let q = (from event in Events
                                 join vg in MachineGroupings on event.MachineId equals vg.MachineId
                                 where vg.MachineGroupId == machineGroup.MachineGroupId
                                 where event.TimeStamp >= template.TimeStamp
                                 orderby (template.Highest ? event.Amount : event.EventId) descending
                                 select _makeMachineGroupHistory(event.EventId, template.TemplateId, machineGroup.MachineGroupId))
                        select q.Take(template.MaxResults)).WithTranslations())
        MachineGroupHistories.InsertAllOnSubmit(vgh);

It takes a defined maximum number of events per group-template combination.

Anyway, this trick sped up the query by four times or so.


来源: stackexchange

问:
Find the section or page of a VBA controls object
How can I identify if a controls object (such as acTextBox) is member of a pages collection in VBA?

When a control object has the focus, a function is called to move the focus to the next control.tabindex based on the type of key which is used. I managed to do this with Sendkeys "{TAB}", but I want to change this since this method constantly disables NUMLOCK on the keyboard.

So far the function below works, but the procedure considers all controls in a form. It should only consider the controls within the same section or page where the function is called from. To accomplish this I need to know if the active control is located within a page and/or section and if it is, the name or index of this page/section. I cannot find the code to do this.

```<code>Public Function GotoNextTab()
    Dim ctlNext, ctlCurrent As Control
    Dim frmCurrent As Form
    Dim lngNextTab As Long
    Set frmCurrent = Screen.Activeform
    Set ctlCurrent = Forms(frmCurrent.Name).ActiveControl

    lngNextTab = Val(ctlCurrent.TabIndex) + 1

    Do Until lngNextTab = frmCurrent.Controls.Count
        For Each ctlNext In frmCurrent.Controls
            Select Case ctlNext.ControlType
                Case acCheckBox, _
                     acComboBox, _
                     acCommandButton, _
                     acListBox, _
                     acOptionButton, _
                     acSubform, _
                     acTabCtl, _
                     acTextBox, _
                     acToggleButton
                        If ctlNext.TabIndex = lngNextTab Then
                            If ctlNext.TabStop = True Then
                                'Make sure that the focus can be set here!
                                If ctlNext.Visible = True And ctlNext.Enabled = True Then
                                    ctlNext.SetFocus
                                    Exit Function
                                Else
                                    'Focus could not be moved, so increase lngNextTab
                                    lngNextTab = lngNextTab + 1
                                End If
                            Else
                                'This was the last tab, so exit
                                Exit Function
                            End If
                        End If
            End Select
        Next ctlNext
    Loop
End Function
</code>```

答:
Consider using the TabControl.Pages() collection to access controls on specific tab pages.

Below is an example to: first find the corresponding page of active control looping through all controls in each tab page; then assign current page and loop through all its controls. Checking by name is reliable since every control with or without tabs on a form must be unique.

```<code>...
Dim currpage As Page
Dim tabCtrl As Control
Dim pagename As String

' FIND CURRENT PAGE OF ACTIVE CONTROL
For Each currpage In Forms!myForm!TabCtl.Pages
    For Each tabctrl In currpage.Controls
       If tabctrl.Name = ctlCurrent.Name
           pagename = currpage.Name
       End If
    Next tabctrl
Next currpage

If Len(pagename) > 0 Then
   ' ASSIGN CURRENT TAB PAGE
   Set currpage = Forms!myForm!mytabCtl.Pages(pagename)

   ' LOOP THROUGH ALL CONTROLS ON CURRENT PAGE
   For Each tabctrl In currpage.Controls
       '...PROCESS EACH CTRL OF CURRENT TAB PAGE
   Next tabctrl

   Set tabctrl = Nothing
   Set currpage = Nothing
End If
</code>```

ContentLicense: CC BY-SA 3.0

Body:
How can I identify if a controls object (such as acTextBox) is member of a pages collection in VBA?

When a control object has the focus, a function is called to move the focus to the next control.tabindex based on the type of key which is used. I managed to do this with Sendkeys "{TAB}", but I want to change this since this method constantly disables NUMLOCK on the keyboard.

So far the function below works, but the procedure considers all controls in a form. It should only consider the controls within the same section or page where the function is called from. To accomplish this I need to know if the active control is located within a page and/or section and if it is, the name or index of this page/section. I cannot find the code to do this.

Public Function GotoNextTab()
    Dim ctlNext, ctlCurrent As Control
    Dim frmCurrent As Form
    Dim lngNextTab As Long
    Set frmCurrent = Screen.Activeform
    Set ctlCurrent = Forms(frmCurrent.Name).ActiveControl

    lngNextTab = Val(ctlCurrent.TabIndex) + 1

    Do Until lngNextTab = frmCurrent.Controls.Count
        For Each ctlNext In frmCurrent.Controls
            Select Case ctlNext.ControlType
                Case acCheckBox, _
                     acComboBox, _
                     acCommandButton, _
                     acListBox, _
                     acOptionButton, _
                     acSubform, _
                     acTabCtl, _
                     acTextBox, _
                     acToggleButton
                        If ctlNext.TabIndex = lngNextTab Then
                            If ctlNext.TabStop = True Then
                                'Make sure that the focus can be set here!
                                If ctlNext.Visible = True And ctlNext.Enabled = True Then
                                    ctlNext.SetFocus
                                    Exit Function
                                Else
                                    'Focus could not be moved, so increase lngNextTab
                                    lngNextTab = lngNextTab + 1
                                End If
                            Else
                                'This was the last tab, so exit
                                Exit Function
                            End If
                        End If
            End Select
        Next ctlNext
    Loop
End Function

Body:
Consider using the TabControl.Pages() collection to access controls on specific tab pages.

Below is an example to: first find the corresponding page of active control looping through all controls in each tab page; then assign current page and loop through all its controls. Checking by name is reliable since every control with or without tabs on a form must be unique.

...
Dim currpage As Page
Dim tabCtrl As Control
Dim pagename As String

' FIND CURRENT PAGE OF ACTIVE CONTROL
For Each currpage In Forms!myForm!TabCtl.Pages
    For Each tabctrl In currpage.Controls
       If tabctrl.Name = ctlCurrent.Name
           pagename = currpage.Name
       End If
    Next tabctrl
Next currpage

If Len(pagename) > 0 Then
   ' ASSIGN CURRENT TAB PAGE
   Set currpage = Forms!myForm!mytabCtl.Pages(pagename)

   ' LOOP THROUGH ALL CONTROLS ON CURRENT PAGE
   For Each tabctrl In currpage.Controls
       '...PROCESS EACH CTRL OF CURRENT TAB PAGE
   Next tabctrl

   Set tabctrl = Nothing
   Set currpage = Nothing
End If


问:
How do you name a property of an object with a string plus a variable?
If I have an object:

```<code>var enemies = {};
var enemyNumber = 0;
</code>```

and then how do I make a new property of that object which is named after a string + a variable, like this (I know this is not valid javascript):

```<code>enemyNumber++;
enemies.enemy + enemyNumber.toString() = {};
</code>```

(enemies.enemy + enemyNumber.toString() is another object)

答:
This is how:

```<code>enemies['enemy' + enemyNumber] = {}
</code>```

In JavaScript, the dot operator is interchangeable with bracket notation.  Which means enemies.enemy1 is the same as enemies['enemy1'].  The bracket notation is more indirect, which allows you to use expressions to refer to the object's properties.

Body:
If I have an object:

var enemies = {};
var enemyNumber = 0;

and then how do I make a new property of that object which is named after a string + a variable, like this (I know this is not valid javascript):

enemyNumber++;
enemies.enemy + enemyNumber.toString() = {};

(enemies.enemy + enemyNumber.toString() is another object)

Body:
This is how:

enemies['enemy' + enemyNumber] = {}

In JavaScript, the dot operator is interchangeable with bracket notation.  Which means enemies.enemy1 is the same as enemies['enemy1'].  The bracket notation is more indirect, which allows you to use expressions to refer to the object's properties.


问:
Laravel 5.3 : Method [show] does not exist
When post my form to the controller, the laravel shows this error:

Method PTA_OIMS\Http\Controllers\InstructionsController::show() does
  not exist in
  /home/rad/public_html/pta_oims/vendor/laravel/framework/src/Illuminate/Routing/Route.php:333

this is my web.php file:

```<code>Route::post('instructions/view','InstructionsController@view')->name('view');
Route::post('instructions/assign','InstructionsController@assign');
Route::get('instructions/sent','InstructionsController@sent')->name('sent');
Route::post('instructions/reject','InstructionsController@reject')->name('reject');
Route::resource('instructions','InstructionsController');
</code>```

and blade view:

```<code> <form action=" {{url('instructions/assign')}}"
</code>```

Became more complete:

InstructionsController and added show(),view() and assign() method

```<code>public function show()
{
    return 'show() method done!!';
}
</code>```

view() method

```<code>public function view(Request $request)
{
    $boxes = $this->getBoxesList();
    $id = $request->input('id');
    $data = Kartable::where('id', '=', $id)
        ->with('instruction')
        ->first();
    if ($data->view_date == NULL) {
        $this->insertViewDate($id);
    }

    return view('instructions.view', array('data' => $data, 'boxes' => $boxes));
}
</code>```

view blade file, The form that sends the data to assign() method:

```<code><form method="POST" action=" {{url('instructions/assign')}}"
    class="form-horizontal" role="form" data-toggle="validator">

    {{csrf_field()}}
</code>```

assign() method

```<code>public function assign(Request $input)
{
    try {

        $inst_id = $input->input('inst_id');
//        $childsInsts = Instructions::where('parent_id', '=', $inst_id)
//             ->where('status', '=', 0)
//             ->get();
        $formData = $input->all();
        $step = 0;
        foreach ($formData['box'] as $box) {
            foreach ($box as $id_reciver)
                DB::transaction(function () use ($formData, $inst_id, $id_reciver, $step) {
                    $kar = new Kartable();

                    $kartable_id = $formData['kartable_id'];
                    $current_box = $formData['current_box'];
                    $kar->inst_id = $inst_id;
                    $kar->parent_id = $kartable_id;
                    $kar->id_sender = $current_box;
                    $kar->id_reciver = $id_reciver;
                    $kar->status = 1;
                    $kar->save(); // insert for new record of kartable
                    $step += 1;
                    if ($step < 2) {
                        $kartable = new Kartable();
                        $kartable
                            ->where('id', '=', $kartable_id)
                            ->update(['status' => 3]); //change status of old row kartable
                    }
                });

            return redirect()->route('instructions.index');
        }
    } catch (\Exception $e) {
        dd($e);
    }
}
</code>```

答:
I would imagine this is because you don't have a method= on your <form> tag which will cause the form to be submitted with a GET request and seeing as you have a Route::resource set up it will assume you're trying to access the show method.

Change your form tag to be:

```<code><form method="POST" action="{{ url('instructions/assign') }}">
</code>```

Also, don't forget to add:

```<code>{{ csrf_field() }}
</code>```

inside your form so that you don't get a TokenMismatchException.

Hope this helps!

Body:
When post my form to the controller, the laravel shows this error:

Method PTA_OIMS\Http\Controllers\InstructionsController::show() does
  not exist in
  /home/rad/public_html/pta_oims/vendor/laravel/framework/src/Illuminate/Routing/Route.php:333

this is my web.php file:

Route::post('instructions/view','InstructionsController@view')->name('view');
Route::post('instructions/assign','InstructionsController@assign');
Route::get('instructions/sent','InstructionsController@sent')->name('sent');
Route::post('instructions/reject','InstructionsController@reject')->name('reject');
Route::resource('instructions','InstructionsController');

and blade view:

 <form action=" {{url('instructions/assign')}}"

Became more complete:

InstructionsController and added show(),view() and assign() method

public function show()
{
    return 'show() method done!!';
}

view() method

public function view(Request $request)
{
    $boxes = $this->getBoxesList();
    $id = $request->input('id');
    $data = Kartable::where('id', '=', $id)
        ->with('instruction')
        ->first();
    if ($data->view_date == NULL) {
        $this->insertViewDate($id);
    }

    return view('instructions.view', array('data' => $data, 'boxes' => $boxes));
}

view blade file, The form that sends the data to assign() method:

<form method="POST" action=" {{url('instructions/assign')}}"
    class="form-horizontal" role="form" data-toggle="validator">

    {{csrf_field()}}

assign() method

public function assign(Request $input)
{
    try {

        $inst_id = $input->input('inst_id');
//        $childsInsts = Instructions::where('parent_id', '=', $inst_id)
//             ->where('status', '=', 0)
//             ->get();
        $formData = $input->all();
        $step = 0;
        foreach ($formData['box'] as $box) {
            foreach ($box as $id_reciver)
                DB::transaction(function () use ($formData, $inst_id, $id_reciver, $step) {
                    $kar = new Kartable();

                    $kartable_id = $formData['kartable_id'];
                    $current_box = $formData['current_box'];
                    $kar->inst_id = $inst_id;
                    $kar->parent_id = $kartable_id;
                    $kar->id_sender = $current_box;
                    $kar->id_reciver = $id_reciver;
                    $kar->status = 1;
                    $kar->save(); // insert for new record of kartable
                    $step += 1;
                    if ($step < 2) {
                        $kartable = new Kartable();
                        $kartable
                            ->where('id', '=', $kartable_id)
                            ->update(['status' => 3]); //change status of old row kartable
                    }
                });

            return redirect()->route('instructions.index');
        }
    } catch (\Exception $e) {
        dd($e);
    }
}

Body:
I would imagine this is because you don't have a method= on your <form> tag which will cause the form to be submitted with a GET request and seeing as you have a Route::resource set up it will assume you're trying to access the show method.

Change your form tag to be:

<form method="POST" action="{{ url('instructions/assign') }}">

Also, don't forget to add:

{{ csrf_field() }}

inside your form so that you don't get a TokenMismatchException.

Hope this helps!


问:
How to pass objects in angular2 material's dialog?
My dialog contains a form that populates an object "someresult" I want that object to be passed back to the app component after the user clicks "OK" on the dialog box. How do I do this?

I included a simple example in this PLUNKR.
http://plnkr.co/edit/qjpY6m5C8bgJjRfm4Yot?p=preview

```<code>import { MdDialogRef } from '@angular/material';
import { Component } from '@angular/core';
@Component({
    selector: 'confirm-dialog',
    template: `
        <p>{{ title }}</p>
        <p>{{ message }}</p>

        <button type="button" md-raised-button
            md-dialog-close="someresult">OK</button>

        <button type="button" md-button
            (click)="dialogRef.close()">Cancel</button>
    `,
})

    export class ConfirmDialog {

        public title: string;
        public message: string;
        public someresult = { // this is the object I want to pass back
          'key': 'somevalue'
        }

        constructor(public dialogRef: MdDialogRef<ConfirmDialog>) {

        }
    }
</code>```

In my app.component.ts I want to be abl eto log out the result using console.log, I can't seem to get the object to log out properly...

```<code>  public openDialog() {
    this.dialogsService
      .confirm('Confirm Dialog', 'Are you sure you want to do this?')
      .subscribe(res => {this.result = res; console.log(res.key);});
  }
</code>```

Note that if I logged console.log(key), I see [Object object] in the console, but when I try to access the key "key", I get an undefined...

答:
I was able to access key value. ? safe navigation ignores key when it's undefined or null.

Edited demo of your Plunker.

Body:
My dialog contains a form that populates an object "someresult" I want that object to be passed back to the app component after the user clicks "OK" on the dialog box. How do I do this?

I included a simple example in this PLUNKR.
http://plnkr.co/edit/qjpY6m5C8bgJjRfm4Yot?p=preview

import { MdDialogRef } from '@angular/material';
import { Component } from '@angular/core';
@Component({
    selector: 'confirm-dialog',
    template: `

{{ title }}

{{ message }}

        <button type="button" md-raised-button
            md-dialog-close="someresult">OK</button>

        <button type="button" md-button
            (click)="dialogRef.close()">Cancel</button>
    `,
})

    export class ConfirmDialog {

        public title: string;
        public message: string;
        public someresult = { // this is the object I want to pass back
          'key': 'somevalue'
        }

        constructor(public dialogRef: MdDialogRef<ConfirmDialog>) {

        }
    }

In my app.component.ts I want to be abl eto log out the result using console.log, I can't seem to get the object to log out properly...

  public openDialog() {
    this.dialogsService
      .confirm('Confirm Dialog', 'Are you sure you want to do this?')
      .subscribe(res => {this.result = res; console.log(res.key);});
  }

Note that if I logged console.log(key), I see [Object object] in the console, but when I try to access the key "key", I get an undefined...


问:
How to make exceptions for url securing app with Keycloak?
We have an app on Wildfly Server, secured with keycloak, everything works fine, but now we have to make an access for an app, deployed on the same server. I don't want to write a "complex" code with all certificates for https and OAuth2, we use for it, but I would like to grant an access for the second app from localhost, to make request on the first one (via rest-api) and get an response. When I check with curl from terminal of the server - I get also an Unathorized-Error, so I need to do all the same operations as for public access (take Token for access from OAuth provider). How could I set up Keycloak, to grant an access from localhost, for example. I haven't found smth. equal neither in Keycloak nor in standalone-full.xml (there are no any properties for this), where I could put exclusions.

I appreciate your help!

答: Add localhost to Valid Redirect Uris and Web Origins of Keycloak's client or you can simply use * for development purposes so that all Uris are valid.


问:
jQuery - check if all mandatory fields in a section have been answered
I need to run a check on a lightbox popUp to see if all fields that are not optional have been input.

HTML

```<code><div id="manualAddressEntry01" class="container popUp large hidden shadow02 rounded03">
    <div class="popUpHeading">
        <h4>Please enter your full address:</h4>
    </div>
    <div class="popUpContent rounded03">
        <img class="closeContainer cursor" src="resource/nw/images/hires/helpClose.gif"/>
        <div class="fl">
            <label for="form_popup1_HouseName">House Number/Name</label>
            <input class="jsValid_required" id="form_popup1_HouseName" type="text" size="25"/>
        </div>

        <div class="fl" style="padding-left:10px">
            <label for="form_popup1_Street">Street</label>
            <input class="jsValid_required" id="form_popup1_Street" type="text" size="25"/>
        </div>

        <br class="cb"/>

        <input id="form_popup1_AddressLine2" type="text" size="35"/>

        <label for="form_popup1_TownCity">Town/City</label>
        <input class="jsValid_alpha" id="form_popup1_TownCity" type="text" size="35"/>

        <label for="form_popup1_County">County</label>
        <input class="jsValid_alpha jsOptional countyInput" id="form_popup1_County" name="text" type="text" size="35"/>

        <label for="form_popup2_Country">Country</label>
        <select class="countrySelect" name="select" id="form_popup1_CountryList">
            <option value="AF">Afghanistan</option>
            <option value="AL">Albania</option>
        </select>

        <label for="form_p">Postcode</label>
        <input class="jsOptional" id="form_popup1_PostCode" type="text" size="10" maxlength="8"/>
        <img class="cursor submit confirmAllInputs" src="confirmBTN2.gif" id="confirmManualAddressEntry01" style="margin-bottom:-5px;"/>
        <br/>
    </div>
</div>
</code>```

What I need to do
I could go the long way round and check each input field by id, and replicate this, changing id's for each pop up in this format - but I want to write some jQuery that when the ".confirmAllInputs" button at the bottom of the pop up is clicked, it finds all input fields within that ".container" that do not have the class jsOptional, and check if these have all been input.  If not, an error message should be displayed, otherwise, it's all accepted.

I've attempted a few things. The closest I got was :

```<code>$('.confirmAllInputs').click(function(){
    var container = $(this).parents('.container');
    var optionalFields = (container.find('input[class!=jsOptional]').val());
    $(container).each(function(i){
       alert('These are the value of the fields: ' + optionalFields);
    });
});
</code>```

But this only reports back the first fields value. I need to cycle through all and check they are not empty.

答:
This will .find() inputs that do not have the class jsOptional and where the value is "".

```<code>$('.confirmAllInputs').click(function() {
    var missingRequired = $(this).closest('.container')
                                 .find('input[class!=jsOptional][value=""]');
    if (missingRequired.length) {
        alert('there were required fields that were not completed');
    }
});
</code>```

If missingRequired.length is greater than 0, the alert() will fire. You can iterate over the missingRequired collection if needed.

```<code>missingRequired.each( function() {
    alert( this.id + ' is required.' );
});
</code>```

Or create a complete String of the IDs that you can use.

```<code>var str = missingRequired.map( function() {
    return this.id;
}).get().join(", ");

alert( "These are required: " + str );
</code>```

Body:
I need to run a check on a lightbox popUp to see if all fields that are not optional have been input.

HTML

Please enter your full address:

            House Number/Name
            <input class="jsValid_required" id="form_popup1_HouseName" type="text" size="25"/>

            Street
            <input class="jsValid_required" id="form_popup1_Street" type="text" size="25"/>

        <input id="form_popup1_AddressLine2" type="text" size="35"/>

        Town/City
        <input class="jsValid_alpha" id="form_popup1_TownCity" type="text" size="35"/>

        County
        <input class="jsValid_alpha jsOptional countyInput" id="form_popup1_County" name="text" type="text" size="35"/>

        Country
        <select class="countrySelect" name="select" id="form_popup1_CountryList">
            <option value="AF">Afghanistan</option>
            <option value="AL">Albania</option>
        </select>

        Postcode
        <input class="jsOptional" id="form_popup1_PostCode" type="text" size="10" maxlength="8"/>

What I need to do
I could go the long way round and check each input field by id, and replicate this, changing id's for each pop up in this format - but I want to write some jQuery that when the ".confirmAllInputs" button at the bottom of the pop up is clicked, it finds all input fields within that ".container" that do not have the class jsOptional, and check if these have all been input.  If not, an error message should be displayed, otherwise, it's all accepted.

I've attempted a few things. The closest I got was :

$('.confirmAllInputs').click(function(){
    var container = $(this).parents('.container');
    var optionalFields = (container.find('input[class!=jsOptional]').val());
    $(container).each(function(i){
       alert('These are the value of the fields: ' + optionalFields);
    });
});

But this only reports back the first fields value. I need to cycle through all and check they are not empty.

Body:
This will .find() inputs that do not have the class jsOptional and where the value is "".

$('.confirmAllInputs').click(function() {
    var missingRequired = $(this).closest('.container')
                                 .find('input[class!=jsOptional][value=""]');
    if (missingRequired.length) {
        alert('there were required fields that were not completed');
    }
});

If missingRequired.length is greater than 0, the alert() will fire. You can iterate over the missingRequired collection if needed.

missingRequired.each( function() {
    alert( this.id + ' is required.' );
});

Or create a complete String of the IDs that you can use.

var str = missingRequired.map( function() {
    return this.id;
}).get().join(", ");

alert( "These are required: " + str );

ContentLicense: CC BY-SA 2.5


问:
Access Unity StreamingAssets on Android
I wrote some code to get all the folders inside a folder inside the StreamingAssets and then to get all the files in that folder.
It works well on Windows but I can't get it to work on Android.

Here is the code :

```<code>foreach (string s in Directory.GetDirectories(model.path + "/Levels")) {
        GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity);
        el.transform.SetParent(grid1.transform);
        string[] words = s.Split('/');
        #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
                            words = s.Split('\\');
        #endif
        el.GetComponentInChildren<Text>().text = words[words.Length - 1];
        el.GetComponent<Button>().onClick.AddListener(() => {
            MapSizeButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text));
        });
    }
</code>```

I had to add the #if UNITY_STANDALONE_WIN for windows because of the '\'.

Then for the files inside that folder I wrote this :

```<code>foreach (string s in Directory.GetFiles(model.path + "/Levels/" + model.mapSize + "/" + model.colorNumber)) {
        string[] words = s.Split('/');
        #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
                    words = s.Split('\\');
        #endif
        words = words[words.Length - 1].Split('.');
        if (words[1] == "json") {
            GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity);
            el.transform.SetParent(grid3.transform);
            el.GetComponentInChildren<Text>().text = words[0];
            el.GetComponent<Button>().onClick.AddListener(() => {
                levelButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text));
            });
        }
    }
</code>```

I'm using UnityEngine.UI.Directory but I read that it can't be use on Android and I must use WWW instead. Something like this :

```<code>string xmlSetUpPath = "jar:file://" + Application.dataPath + "!/assets/xml/xmlSetUp.xml";

        WWW book1WWW = new WWW(book1Path);
        yield return book1WWW;
        if(!File.Exists(Application.persistentDataPath + "/xml/book1.xml"))
        {
            File.WriteAllBytes(Application.persistentDataPath + "/xml/book1.xml", book1WWW.bytes);
        }
</code>```

However I couldn't find anything like Directory.getFiles() or Directory.getFolder(). So I thought I could use WWW to check if the file exists (as the file names are 1.json, 2.json, 3.json) and iterate until a file doesn't exist.

But I would also need to check if a folder exists for the 1st part of the script and I can't find how to check if a folder exists with WWW. (My folders names are also 1,2,3,4...)

So how to check if a folder exists with WWW ?

Or what else can I do ?

UPDATE :

I updated the code, now it looks like this :

```<code>for (int i = 0; i < 100; i++) {
        if (Directory.Exists(Path.Combine(model.path, "Levels/" + i.ToString()))){
            GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity);
            el.transform.SetParent(grid1.transform);
            el.GetComponentInChildren<Text>().text = i.ToString();
            el.GetComponent<Button>().onClick.AddListener(() => {
                MapSizeButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text));
            });
        }
    }
</code>```

I use path.combine() and check every folder from 0 to 100. It works on Windows but it still doesn't work in Android.

The path is set like this :

```<code>#if UNITY_IPHONE
        path = Application.dataPath + "/Raw";
    #endif

    #if UNITY_ANDROID
        path = "jar:file://" + Application.dataPath + "!/assets";
    #endif

    #if UNITY_STANDALONE || UNITY_EDITOR
        path = Application.dataPath + "/StreamingAssets";
    #endif
</code>```

QUESTION UPDATE

I made a script that generate the file paths. The paths are always the same : "FolderNumerotedFromYToX/FolderNumerotedFromYToX/FileNumerotedFrom1ToX.json". The generation works but the writing to JSON doesn't. It outputs "{}".

```<code>        // Generate level list
    List<KeyValuePair<int, List<KeyValuePair<int, List<int>>>>> l;
    l = new List<KeyValuePair<int, List<KeyValuePair<int, List<int>>>>>();
    for (int i = 1; i < 100; i++) {
        if (Directory.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i.ToString()))) {
            l.Add(new KeyValuePair<int, List<KeyValuePair<int, List<int>>>>(i, new List<KeyValuePair<int, List<int>>>()));
            for (int j = 1; j < 100; j++) {
                if (Directory.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i + "/" + j))) {
                    l[l.Count - 1].Value.Add(new KeyValuePair<int, List<int>>(j, new List<int>()));
                    int k = 1;
                    while (true) {
                        if (File.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i + "/" + j + "/" + k + ".json"))) {
                            l[l.Count - 1].Value[l[l.Count - 1].Value.Count - 1].Value.Add(k);
                        }
                        else
                            break;
                        k++;
                    }
                }
            }
        }
    }
    string ljson = JsonUtility.ToJson(l);
    var lsr = File.CreateText("Assets/StreamingAssets/levels.json");
    lsr.WriteLine(ljson);
    lsr.Close();
</code>```

Can you help me finding a way to store this to a file ?

答:
To solve this problem I created pre-compilation script which will run before the compilation; this script will list the names of the files you want to access later in text file

```<code> #if UNITY_EDITOR
 using UnityEditor.Build;
 using UnityEditor;
 using System.IO;

 public class BM_AndroidBuildPrepartion : IPreprocessBuild
 {
     public int callbackOrder { get { return 0; } }
     public void OnPreprocessBuild(BuildTarget target, string path)
     {
         // Do the preprocessing here
         string[] fileEntries = Directory.GetFiles("Assets/Resources/Prefabs/alphabet", "*.prefab");
         System.IO.Directory.CreateDirectory("Assets/StreamingAssets/");
         using (StreamWriter sw = new StreamWriter("Assets/StreamingAssets/alphabet.txt", false))
         {

         foreach (string filename in fileEntries) {
                 sw.WriteLine(Path.GetFileNameWithoutExtension(filename));
         }

         }
     }
 }
 #endif
</code>```

then I read the text file and you can access the files in same way but you have to put them inside your project in Assets/StreamingAssets/

```<code>#if UNITY_ANDROID
        string  path = "jar:file://" + Application.dataPath + "!/assets/alphabet.txt";
          WWW wwwfile = new WWW(path);
          while (!wwwfile.isDone) { }
          var filepath = string.Format("{0}/{1}", Application.persistentDataPath, "alphabet.t");
          File.WriteAllBytes(filepath, wwwfile.bytes);

          StreamReader wr = new StreamReader(filepath);
              string line;
              while ((line = wr.ReadLine()) != null)
              {
              //your code
              }
   #endif
</code>```

Title: Access Unity StreamingAssets on Android

Body:
I wrote some code to get all the folders inside a folder inside the StreamingAssets and then to get all the files in that folder.
It works well on Windows but I can't get it to work on Android.

Here is the code :

foreach (string s in Directory.GetDirectories(model.path + "/Levels")) {
        GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity);
        el.transform.SetParent(grid1.transform);
        string[] words = s.Split('/');
        #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
                            words = s.Split('\\');
        #endif
        el.GetComponentInChildren<Text>().text = words[words.Length - 1];
        el.GetComponent<Button>().onClick.AddListener(() => {
            MapSizeButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text));
        });
    }

I had to add the #if UNITY_STANDALONE_WIN for windows because of the '\'.

Then for the files inside that folder I wrote this :

foreach (string s in Directory.GetFiles(model.path + "/Levels/" + model.mapSize + "/" + model.colorNumber)) {
        string[] words = s.Split('/');
        #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
                    words = s.Split('\\');
        #endif
        words = words[words.Length - 1].Split('.');
        if (words[1] == "json") {
            GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity);
            el.transform.SetParent(grid3.transform);
            el.GetComponentInChildren<Text>().text = words[0];
            el.GetComponent<Button>().onClick.AddListener(() => {
                levelButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text));
            });
        }
    }

I'm using UnityEngine.UI.Directory but I read that it can't be use on Android and I must use WWW instead. Something like this :

string xmlSetUpPath = "jar:file://" + Application.dataPath + "!/assets/xml/xmlSetUp.xml";

        WWW book1WWW = new WWW(book1Path);
        yield return book1WWW;
        if(!File.Exists(Application.persistentDataPath + "/xml/book1.xml"))
        {
            File.WriteAllBytes(Application.persistentDataPath + "/xml/book1.xml", book1WWW.bytes);
        }

However I couldn't find anything like Directory.getFiles() or Directory.getFolder(). So I thought I could use WWW to check if the file exists (as the file names are 1.json, 2.json, 3.json) and iterate until a file doesn't exist.

But I would also need to check if a folder exists for the 1st part of the script and I can't find how to check if a folder exists with WWW. (My folders names are also 1,2,3,4...)

So how to check if a folder exists with WWW ?

Or what else can I do ?

UPDATE :

I updated the code, now it looks like this :

for (int i = 0; i < 100; i++) {
        if (Directory.Exists(Path.Combine(model.path, "Levels/" + i.ToString()))){
            GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity);
            el.transform.SetParent(grid1.transform);
            el.GetComponentInChildren<Text>().text = i.ToString();
            el.GetComponent<Button>().onClick.AddListener(() => {
                MapSizeButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text));
            });
        }
    }

I use path.combine() and check every folder from 0 to 100. It works on Windows but it still doesn't work in Android.

The path is set like this :

#if UNITY_IPHONE
        path = Application.dataPath + "/Raw";
    #endif

    #if UNITY_ANDROID
        path = "jar:file://" + Application.dataPath + "!/assets";
    #endif

    #if UNITY_STANDALONE || UNITY_EDITOR
        path = Application.dataPath + "/StreamingAssets";
    #endif

QUESTION UPDATE

I made a script that generate the file paths. The paths are always the same : "FolderNumerotedFromYToX/FolderNumerotedFromYToX/FileNumerotedFrom1ToX.json". The generation works but the writing to JSON doesn't. It outputs "{}".

        // Generate level list
    List<KeyValuePair<int, List<KeyValuePair<int, List<int>>>>> l;
    l = new List<KeyValuePair<int, List<KeyValuePair<int, List<int>>>>>();
    for (int i = 1; i < 100; i++) {
        if (Directory.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i.ToString()))) {
            l.Add(new KeyValuePair<int, List<KeyValuePair<int, List<int>>>>(i, new List<KeyValuePair<int, List<int>>>()));
            for (int j = 1; j < 100; j++) {
                if (Directory.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i + "/" + j))) {
                    l[l.Count - 1].Value.Add(new KeyValuePair<int, List<int>>(j, new List<int>()));
                    int k = 1;
                    while (true) {
                        if (File.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i + "/" + j + "/" + k + ".json"))) {
                            l[l.Count - 1].Value[l[l.Count - 1].Value.Count - 1].Value.Add(k);
                        }
                        else
                            break;
                        k++;
                    }
                }
            }
        }
    }
    string ljson = JsonUtility.ToJson(l);
    var lsr = File.CreateText("Assets/StreamingAssets/levels.json");
    lsr.WriteLine(ljson);
    lsr.Close();

Can you help me finding a way to store this to a file ?

Body:
To solve this problem I created pre-compilation script which will run before the compilation; this script will list the names of the files you want to access later in text file

 #if UNITY_EDITOR
 using UnityEditor.Build;
 using UnityEditor;
 using System.IO;

 public class BM_AndroidBuildPrepartion : IPreprocessBuild
 {
     public int callbackOrder { get { return 0; } }
     public void OnPreprocessBuild(BuildTarget target, string path)
     {
         // Do the preprocessing here
         string[] fileEntries = Directory.GetFiles("Assets/Resources/Prefabs/alphabet", "*.prefab");
         System.IO.Directory.CreateDirectory("Assets/StreamingAssets/");
         using (StreamWriter sw = new StreamWriter("Assets/StreamingAssets/alphabet.txt", false))
         {

         foreach (string filename in fileEntries) {
                 sw.WriteLine(Path.GetFileNameWithoutExtension(filename));
         }

         }
     }
 }
 #endif

then I read the text file and you can access the files in same way but you have to put them inside your project in Assets/StreamingAssets/

#if UNITY_ANDROID
        string  path = "jar:file://" + Application.dataPath + "!/assets/alphabet.txt";
          WWW wwwfile = new WWW(path);
          while (!wwwfile.isDone) { }
          var filepath = string.Format("{0}/{1}", Application.persistentDataPath, "alphabet.t");
          File.WriteAllBytes(filepath, wwwfile.bytes);

          StreamReader wr = new StreamReader(filepath);
              string line;
              while ((line = wr.ReadLine()) != null)
              {
              //your code
              }
   #endif


问:
Optimizing a Sort Method
I have a program that needs to sort matches into the following order (the following is a short example):

```<code>PIT
PREDICTIONS
Match 1
Match 2
Quarters 1 Match 1
Quarters 1 Match 2
Quarters 2 Match 1
Semis 1
Semis 2
Finals 1
Finals 2
</code>```

Note: There can be unlimited Matches, Quarters 1 - 4 only (with unlimited submatches), unlimited semis, and unlimited finals.

I've got the following method that assign a score to one of the above titles:

```<code>public static long getMatchScore(String name) {
    long score = 0;
    String matchName = name.toLowerCase();
    String[] tokens = matchName.split("\\s+");

    if(matchName.startsWith("pit")) score -= 100000;
    else if(matchName.startsWith("predictions")) score -= 1000;
    else if(matchName.startsWith("quals")) score = Integer.parseInt(matchName.split("\\s+")[1]);
    else if(matchName.startsWith("quarters")) {
        if(Integer.parseInt(tokens[1]) == 1) score += 1000;
        else if(Integer.parseInt(tokens[1]) == 2) score += 10000;
        else if(Integer.parseInt(tokens[1]) == 3) score += 100000;
        else if(Integer.parseInt(tokens[1]) == 4) score += 1000000;

        score += Integer.parseInt(tokens[3]);
    }
    else if(matchName.startsWith("semis")) {
        if(Integer.parseInt(tokens[1]) == 1) score += 10000000;
        else if(Integer.parseInt(tokens[1]) == 2) score += 100000000;

        score += Integer.parseInt(tokens[3]);
    }
    else if(matchName.startsWith("finals")) {
        score += 1000000000;
        score += Integer.parseInt(tokens[1]);
    }
    return score;
}
</code>```

Then the Java method compareTo() is used to sort it. Is there a better way to do this rather than assigning massive numbers like 100000000.

答:
This one calls for embedding the logic in your code into a Comparable class.

```<code>import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MatchDescription implements Comparable<MatchDescription> {

    private MatchType matchType;
    private int matchOrder = 0;
    private int subMatchOrder = 0;

    public MatchDescription(String name) {
        String matchName = name.toLowerCase().trim();
        String[] tokens = matchName.split("\\s+");

        matchType = MatchType.getByName(tokens[0]);

        if (matchType.hasMatchOrder()) {
            matchOrder = Integer.parseInt(tokens[1]);
        }
        if (matchType.hasSubmatches()) {
            subMatchOrder = Integer.parseInt(tokens[3]);
        }
    }
</code>```

Now, methods compareTo(T) and equals(Object) are overridden using the logic of the matches order, sub-order etc.

```<code>    @Override
    public int compareTo(MatchDescription other) {
        if (this.matchType == other.matchType)
            if (this.matchOrder == other.matchOrder)
                return (this.subMatchOrder - other.subMatchOrder);
            else
                return (this.matchOrder - other.matchOrder);
        else
            return (this.matchType.getMatchTypeOrder() - other.matchType.getMatchTypeOrder());
    }

    @Override
    public boolean equals(Object other) {
        return (other instanceof MatchDescription) &&
                (((MatchDescription) other).matchType == this.matchType) &&
                (((MatchDescription) other).matchOrder == this.matchOrder);
    }
</code>```

The match types are managed via an inner enum:

```<code>    private enum MatchType {
        PIT("PIT",                 1, false, false),
        PREDICTIONS("PREDICTIONS", 2, false, false),
        MATCH("Match",             3, true,  false),
        QUARTERS("Quarters",       4, true,  true),
        SEMIS("Semis",             5, true,  true),
        FINALS("Finals",           6, true,  false)
        ;

        private String name;
        private int matchTypeOrder;
        private boolean hasMatchOrder;
        private boolean hasSubmatches;

        MatchType(String name, int matchTypeOrder, boolean hasMatchOrder, boolean hasSubmatches) {
            this.name           = name;
            this.matchTypeOrder = matchTypeOrder;
            this.hasMatchOrder  = hasMatchOrder;
            this.hasSubmatches  = hasSubmatches;
        }

        public boolean hasMatchOrder() {
            return hasMatchOrder;
        }

        public boolean hasSubmatches() {
            return hasSubmatches;
        }

        public static MatchType getByName(String matchName) {
            for (MatchType value : values()) {
                if (value.getName().equalsIgnoreCase(matchName))
                    return value;
            }
            return null;
        }

        private String getName() {
            return name;
        }

        public int getMatchTypeOrder() {
            return matchTypeOrder;
        }
    }
</code>```

Finally, toString() presents the object nicely:

```<code>public String toString() {
        String description = matchType.getName();
        if (matchType.hasMatchOrder()) {
            description +=  " " + matchOrder;

            if (matchType.hasSubmatches())
                description +=  " Match " + subMatchOrder;
        }

        return description;
    }
</code>```

This is an example on how to use the comparable object (notice that white spaces are also handled):

```<code>    public static void main(String[] args) {
        String[] inputs = new String[] {
                "PIT  ",
                "       Finals 1  ",
                "PREDICTIONS  ",
            "   Match 2  ",
            "   Quarters 1 Match 1  ",
            "   Quarters 1 Match 2  ",
            "   Match 1  ",
        "       Semis 1  Match 1 ",
        "       Semis 2   Match 1",
        "       Finals 2",
        "   Quarters 2 Match 1  "};

        List<MatchDescription> c = new ArrayList<>();
        for (String input : inputs) {
            c.add(new MatchDescription(input));
        }
        Collections.sort(c);

        for (MatchDescription e : c) {
            System.out.println(e);
        }

    }
}
</code>```

Title: Optimizing a Sort Method

Body:
I have a program that needs to sort matches into the following order (the following is a short example):

PIT
PREDICTIONS
Match 1
Match 2
Quarters 1 Match 1
Quarters 1 Match 2
Quarters 2 Match 1
Semis 1
Semis 2
Finals 1
Finals 2

Note: There can be unlimited Matches, Quarters 1 - 4 only (with unlimited submatches), unlimited semis, and unlimited finals.

I've got the following method that assign a score to one of the above titles:

public static long getMatchScore(String name) {
    long score = 0;
    String matchName = name.toLowerCase();
    String[] tokens = matchName.split("\\s+");

    if(matchName.startsWith("pit")) score -= 100000;
    else if(matchName.startsWith("predictions")) score -= 1000;
    else if(matchName.startsWith("quals")) score = Integer.parseInt(matchName.split("\\s+")[1]);
    else if(matchName.startsWith("quarters")) {
        if(Integer.parseInt(tokens[1]) == 1) score += 1000;
        else if(Integer.parseInt(tokens[1]) == 2) score += 10000;
        else if(Integer.parseInt(tokens[1]) == 3) score += 100000;
        else if(Integer.parseInt(tokens[1]) == 4) score += 1000000;

        score += Integer.parseInt(tokens[3]);
    }
    else if(matchName.startsWith("semis")) {
        if(Integer.parseInt(tokens[1]) == 1) score += 10000000;
        else if(Integer.parseInt(tokens[1]) == 2) score += 100000000;

        score += Integer.parseInt(tokens[3]);
    }
    else if(matchName.startsWith("finals")) {
        score += 1000000000;
        score += Integer.parseInt(tokens[1]);
    }
    return score;
}

Then the Java method compareTo() is used to sort it. Is there a better way to do this rather than assigning massive numbers like 100000000.

Body:
This one calls for embedding the logic in your code into a Comparable class.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MatchDescription implements Comparable<MatchDescription> {

    private MatchType matchType;
    private int matchOrder = 0;
    private int subMatchOrder = 0;

    public MatchDescription(String name) {
        String matchName = name.toLowerCase().trim();
        String[] tokens = matchName.split("\\s+");

        matchType = MatchType.getByName(tokens[0]);

        if (matchType.hasMatchOrder()) {
            matchOrder = Integer.parseInt(tokens[1]);
        }
        if (matchType.hasSubmatches()) {
            subMatchOrder = Integer.parseInt(tokens[3]);
        }
    }

Now, methods compareTo(T) and equals(Object) are overridden using the logic of the matches order, sub-order etc.

    @Override
    public int compareTo(MatchDescription other) {
        if (this.matchType == other.matchType)
            if (this.matchOrder == other.matchOrder)
                return (this.subMatchOrder - other.subMatchOrder);
            else
                return (this.matchOrder - other.matchOrder);
        else
            return (this.matchType.getMatchTypeOrder() - other.matchType.getMatchTypeOrder());
    }

    @Override
    public boolean equals(Object other) {
        return (other instanceof MatchDescription) &&
                (((MatchDescription) other).matchType == this.matchType) &&
                (((MatchDescription) other).matchOrder == this.matchOrder);
    }

The match types are managed via an inner enum:

    private enum MatchType {
        PIT("PIT",                 1, false, false),
        PREDICTIONS("PREDICTIONS", 2, false, false),
        MATCH("Match",             3, true,  false),
        QUARTERS("Quarters",       4, true,  true),
        SEMIS("Semis",             5, true,  true),
        FINALS("Finals",           6, true,  false)
        ;

        private String name;
        private int matchTypeOrder;
        private boolean hasMatchOrder;
        private boolean hasSubmatches;

        MatchType(String name, int matchTypeOrder, boolean hasMatchOrder, boolean hasSubmatches) {
            this.name           = name;
            this.matchTypeOrder = matchTypeOrder;
            this.hasMatchOrder  = hasMatchOrder;
            this.hasSubmatches  = hasSubmatches;
        }

        public boolean hasMatchOrder() {
            return hasMatchOrder;
        }

        public boolean hasSubmatches() {
            return hasSubmatches;
        }

        public static MatchType getByName(String matchName) {
            for (MatchType value : values()) {
                if (value.getName().equalsIgnoreCase(matchName))
                    return value;
            }
            return null;
        }

        private String getName() {
            return name;
        }

        public int getMatchTypeOrder() {
            return matchTypeOrder;
        }
    }

Finally, toString() presents the object nicely:

public String toString() {
        String description = matchType.getName();
        if (matchType.hasMatchOrder()) {
            description +=  " " + matchOrder;

            if (matchType.hasSubmatches())
                description +=  " Match " + subMatchOrder;
        }

        return description;
    }

This is an example on how to use the comparable object (notice that white spaces are also handled):

    public static void main(String[] args) {
        String[] inputs = new String[] {
                "PIT  ",
                "       Finals 1  ",
                "PREDICTIONS  ",
            "   Match 2  ",
            "   Quarters 1 Match 1  ",
            "   Quarters 1 Match 2  ",
            "   Match 1  ",
        "       Semis 1  Match 1 ",
        "       Semis 2   Match 1",
        "       Finals 2",
        "   Quarters 2 Match 1  "};

        List<MatchDescription> c = new ArrayList<>();
        for (String input : inputs) {
            c.add(new MatchDescription(input));
        }
        Collections.sort(c);

        for (MatchDescription e : c) {
            System.out.println(e);
        }

    }
}


问:
VB.NET Update existing XML with new section
I am working in a vb.net project, I would like to update an existing XML with a new section,

```<code><BookUpdateable Action="Renew">
    <BookOption>Book</BookOption>
    <BookMaster Action="None">
        <Key>
          <MasterReference>7678812382</MasterReference>
        </Key>
        <Assured Action="Update" xsi:type="OrgDataUpdateable">
          <Key>
            <CaptionCode>BOOKINTRO</CaptionCode>
            <PrevTransaction>0</PrevTransaction>
          </Key>
          <Addresses>
            <IsDeleted>true</IsDeleted>
          </Addresses>
        </Assured>
        <Units>
          <IsDeleted>true</IsDeleted>
        </Units>
        <Sections>
          <SectionDataUpdateable Action="Update" SectionTypeCode="NEW" SubSectionTypeCode="ONE">
            <Key>
              <SectionSequence>10</SectionSequence>
            </Key>
            <IsDeleted>true</IsDeleted>
          </SectionDataUpdateable>
  /*************************************************
  NEW  SECTION TO BE ADDED HERE
  *************************************************/
        </Sections>
        <BookDataExts>
          <MasterStatusCode>BOOKEXTN</MasterStatusCode>
          <EffectiveDate>2017-07-28</EffectiveDate>
        </BookDataExts>
    </BookMaster>
    <ReturnFields>false</ReturnFields>
</BookUpdateable>
</code>```

I have tried like this, but not working,

```<code>nameCodeSections = xDoc.SelectSingleNode("/r:BookUpdateable[1]/r:BookMaster", xNsMgr)
Dim childNode As XmlNode = xDoc.CreateNode(XmlNodeType.Element, "Sections", "")
Dim newAttribute As XmlAttribute = xDoc.CreateAttribute("SectionDataUpdateable", Str, "")
childNode.Attributes.Append(newAttribute)
nameCodeSections.AppendChild(childNode)
</code>```

I need to insert another section under sections element like this

```<code><SectionDataUpdateable Action="Update" SectionTypeCode="OLD"     SubSectionTypeCode="TWO">
<Key>
<SectionSequence>05</SectionSequence>
</Key>
<IsDeleted>true</IsDeleted>
</SectionDataUpdateable>
</code>```

答:
The location of the text "NEW  SECTION TO BE ADDED HERE" in your example suggests that you want the new data to be added as the last sibling to the first <SectionDataUpdateable />. So I used this sample XML:

```<code><?xml version="1.0" encoding="utf-8" standalone="yes"?>
<BookUpdateable Action="Renew">
    <BookOption>Book</BookOption>
    <BookMaster Action="None">
        <Key>
          <MasterReference>7678812382</MasterReference>
        </Key>
        <Assured Action="Update" xsi:type="OrgDataUpdateable">
          <Key>
            <CaptionCode>BOOKINTRO</CaptionCode>
            <PrevTransaction>0</PrevTransaction>
          </Key>
          <Addresses>
            <IsDeleted>true</IsDeleted>
          </Addresses>
        </Assured>
        <Units>
          <IsDeleted>true</IsDeleted>
        </Units>
        <Sections>
          <SectionDataUpdateable Action="Update" SectionTypeCode="NEW" SubSectionTypeCode="ONE">
            <Key>
              <SectionSequence>10</SectionSequence>
            </Key>
            <IsDeleted>true</IsDeleted>
          </SectionDataUpdateable>
          <SectionDataUpdateable Action="Nothing" SectionTypeCode="TEST" SubSectionTypeCode="ONE">
            <Key>
              <SectionSequence>99</SectionSequence>
            </Key>
            <IsDeleted>dontcare</IsDeleted>
          </SectionDataUpdateable>
          <!--
            /*********************************************
            NEW SECTION TO BE INSERTED BEFORE THIS COMMENT
            *********************************************/
            -->
        </Sections>
        <BookDataExts>
          <MasterStatusCode>BOOKEXTN</MasterStatusCode>
          <EffectiveDate>2017-07-28</EffectiveDate>
        </BookDataExts>
    </BookMaster>
    <ReturnFields>false</ReturnFields>
</BookUpdateable>
</code>```

Without you defining the xmlns parts in the question to make it easier to answer, I had to make something up for "xsi" and remove the "r:".

One thing I have noticed about manipulating XML is that you often need to act on the parent of a node.

So, get the nodes "/BookUpdateable[1]/BookMaster/Sections/SectionDataUpdateable" and insert your new data after the last one:

```<code>Option Infer On
Option Strict On

Imports System.Xml

Module Module1

    Sub Main()
        Dim src = "C:\temp\BookUpdateable.xml"
        Dim dest = "C:\temp\BookUpdateable2.xml"

        Dim xmlDoc As New XmlDocument
        Dim settings = New XmlReaderSettings With {.NameTable = New NameTable()}
        Dim nsm = New XmlNamespaceManager(settings.NameTable)
        nsm.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance")

        Dim context = New XmlParserContext(Nothing, nsm, "", XmlSpace.Default)
        Dim reader = XmlReader.Create(src, settings, context)
        xmlDoc.Load(reader)

        Dim nameCodeSections = xmlDoc.SelectNodes("/BookUpdateable[1]/BookMaster/Sections/SectionDataUpdateable", nsm)

        Dim newData As XElement = <SectionDataUpdateable Action="Update" SectionTypeCode="OLD" SubSectionTypeCode="TWO">
                                      <Key>
                                          <SectionSequence>05</SectionSequence>
                                      </Key>
                                      <IsDeleted>true</IsDeleted>
                                  </SectionDataUpdateable>

        Dim xd = New XmlDocument()
        xd.LoadXml(newData.ToString())

        nameCodeSections(0).ParentNode.InsertAfter(xmlDoc.ImportNode(xd.FirstChild, True), nameCodeSections(nameCodeSections.Count - 1))

        xmlDoc.Save(dest)

        Console.WriteLine("Done.")
        Console.ReadLine()

    End Sub

End Module
</code>```

The running of which results in:

```<code><?xml version="1.0" encoding="utf-8"?>
<BookUpdateable Action="Renew">
  <BookOption>Book</BookOption>
  <BookMaster Action="None">
    <Key>
      <MasterReference>7678812382</MasterReference>
    </Key>
    <Assured Action="Update" xsi:type="OrgDataUpdateable" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Key>
        <CaptionCode>BOOKINTRO</CaptionCode>
        <PrevTransaction>0</PrevTransaction>
      </Key>
      <Addresses>
        <IsDeleted>true</IsDeleted>
      </Addresses>
    </Assured>
    <Units>
      <IsDeleted>true</IsDeleted>
    </Units>
    <Sections>
      <SectionDataUpdateable Action="Update" SectionTypeCode="NEW" SubSectionTypeCode="ONE">
        <Key>
          <SectionSequence>10</SectionSequence>
        </Key>
        <IsDeleted>true</IsDeleted>
      </SectionDataUpdateable>
      <SectionDataUpdateable Action="Nothing" SectionTypeCode="TEST" SubSectionTypeCode="ONE">
        <Key>
          <SectionSequence>99</SectionSequence>
        </Key>
        <IsDeleted>dontcare</IsDeleted>
      </SectionDataUpdateable>
      <SectionDataUpdateable Action="Update" SectionTypeCode="OLD" SubSectionTypeCode="TWO">
        <Key>
          <SectionSequence>05</SectionSequence>
        </Key>
        <IsDeleted>true</IsDeleted>
      </SectionDataUpdateable>
      <!--
            /*********************************************
            NEW SECTION TO BE INSERTED BEFORE THIS COMMENT
            *********************************************/
            -->
    </Sections>
    <BookDataExts>
      <MasterStatusCode>BOOKEXTN</MasterStatusCode>
      <EffectiveDate>2017-07-28</EffectiveDate>
    </BookDataExts>
  </BookMaster>
  <ReturnFields>false</ReturnFields>
</BookUpdateable>
</code>```

You should put in some sanity checks such as testing that nameCodeSections IsNot Nothing before using nameCodeSections(0).

References:

'xsi' is an undeclared prefix using XmlDocument

Converting XElement into XmlNode

Appending an XMLChildnode from one XML to another XML file

Body:
I am working in a vb.net project, I would like to update an existing XML with a new section,

<BookUpdateable Action="Renew">
    <BookOption>Book</BookOption>
    <BookMaster Action="None">
        <Key>
          <MasterReference>7678812382</MasterReference>
        </Key>
        <Assured Action="Update" xsi:type="OrgDataUpdateable">
          <Key>
            <CaptionCode>BOOKINTRO</CaptionCode>
            <PrevTransaction>0</PrevTransaction>
          </Key>
          <Addresses>
            <IsDeleted>true</IsDeleted>
          </Addresses>
        </Assured>
        <Units>
          <IsDeleted>true</IsDeleted>
        </Units>
        <Sections>
          <SectionDataUpdateable Action="Update" SectionTypeCode="NEW" SubSectionTypeCode="ONE">
            <Key>
              <SectionSequence>10</SectionSequence>
            </Key>
            <IsDeleted>true</IsDeleted>
          </SectionDataUpdateable>
  /*************************************************
  NEW  SECTION TO BE ADDED HERE
  *************************************************/
        </Sections>
        <BookDataExts>
          <MasterStatusCode>BOOKEXTN</MasterStatusCode>
          <EffectiveDate>2017-07-28</EffectiveDate>
        </BookDataExts>
    </BookMaster>
    <ReturnFields>false</ReturnFields>
</BookUpdateable>

I have tried like this, but not working,

nameCodeSections = xDoc.SelectSingleNode("/r:BookUpdateable[1]/r:BookMaster", xNsMgr)
Dim childNode As XmlNode = xDoc.CreateNode(XmlNodeType.Element, "Sections", "")
Dim newAttribute As XmlAttribute = xDoc.CreateAttribute("SectionDataUpdateable", Str, "")
childNode.Attributes.Append(newAttribute)
nameCodeSections.AppendChild(childNode)

I need to insert another section under sections element like this

<SectionDataUpdateable Action="Update" SectionTypeCode="OLD"     SubSectionTypeCode="TWO">
<Key>
<SectionSequence>05</SectionSequence>
</Key>
<IsDeleted>true</IsDeleted>
</SectionDataUpdateable>

Body:
The location of the text "NEW  SECTION TO BE ADDED HERE" in your example suggests that you want the new data to be added as the last sibling to the first <SectionDataUpdateable />. So I used this sample XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<BookUpdateable Action="Renew">
    <BookOption>Book</BookOption>
    <BookMaster Action="None">
        <Key>
          <MasterReference>7678812382</MasterReference>
        </Key>
        <Assured Action="Update" xsi:type="OrgDataUpdateable">
          <Key>
            <CaptionCode>BOOKINTRO</CaptionCode>
            <PrevTransaction>0</PrevTransaction>
          </Key>
          <Addresses>
            <IsDeleted>true</IsDeleted>
          </Addresses>
        </Assured>
        <Units>
          <IsDeleted>true</IsDeleted>
        </Units>
        <Sections>
          <SectionDataUpdateable Action="Update" SectionTypeCode="NEW" SubSectionTypeCode="ONE">
            <Key>
              <SectionSequence>10</SectionSequence>
            </Key>
            <IsDeleted>true</IsDeleted>
          </SectionDataUpdateable>
          <SectionDataUpdateable Action="Nothing" SectionTypeCode="TEST" SubSectionTypeCode="ONE">
            <Key>
              <SectionSequence>99</SectionSequence>
            </Key>
            <IsDeleted>dontcare</IsDeleted>
          </SectionDataUpdateable>
          <!--
            /*********************************************
            NEW SECTION TO BE INSERTED BEFORE THIS COMMENT
            *********************************************/
            -->
        </Sections>
        <BookDataExts>
          <MasterStatusCode>BOOKEXTN</MasterStatusCode>
          <EffectiveDate>2017-07-28</EffectiveDate>
        </BookDataExts>
    </BookMaster>
    <ReturnFields>false</ReturnFields>
</BookUpdateable>

Without you defining the xmlns parts in the question to make it easier to answer, I had to make something up for "xsi" and remove the "r:".

One thing I have noticed about manipulating XML is that you often need to act on the parent of a node.

So, get the nodes "/BookUpdateable[1]/BookMaster/Sections/SectionDataUpdateable" and insert your new data after the last one:

Option Infer On
Option Strict On

Imports System.Xml

Module Module1

    Sub Main()
        Dim src = "C:\temp\BookUpdateable.xml"
        Dim dest = "C:\temp\BookUpdateable2.xml"

        Dim xmlDoc As New XmlDocument
        Dim settings = New XmlReaderSettings With {.NameTable = New NameTable()}
        Dim nsm = New XmlNamespaceManager(settings.NameTable)
        nsm.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance")

        Dim context = New XmlParserContext(Nothing, nsm, "", XmlSpace.Default)
        Dim reader = XmlReader.Create(src, settings, context)
        xmlDoc.Load(reader)

        Dim nameCodeSections = xmlDoc.SelectNodes("/BookUpdateable[1]/BookMaster/Sections/SectionDataUpdateable", nsm)

        Dim newData As XElement = <SectionDataUpdateable Action="Update" SectionTypeCode="OLD" SubSectionTypeCode="TWO">
                                      <Key>
                                          <SectionSequence>05</SectionSequence>
                                      </Key>
                                      <IsDeleted>true</IsDeleted>
                                  </SectionDataUpdateable>

        Dim xd = New XmlDocument()
        xd.LoadXml(newData.ToString())

        nameCodeSections(0).ParentNode.InsertAfter(xmlDoc.ImportNode(xd.FirstChild, True), nameCodeSections(nameCodeSections.Count - 1))

        xmlDoc.Save(dest)

        Console.WriteLine("Done.")
        Console.ReadLine()

    End Sub

End Module

The running of which results in:

<?xml version="1.0" encoding="utf-8"?>
<BookUpdateable Action="Renew">
  <BookOption>Book</BookOption>
  <BookMaster Action="None">
    <Key>
      <MasterReference>7678812382</MasterReference>
    </Key>
    <Assured Action="Update" xsi:type="OrgDataUpdateable" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Key>
        <CaptionCode>BOOKINTRO</CaptionCode>
        <PrevTransaction>0</PrevTransaction>
      </Key>
      <Addresses>
        <IsDeleted>true</IsDeleted>
      </Addresses>
    </Assured>
    <Units>
      <IsDeleted>true</IsDeleted>
    </Units>
    <Sections>
      <SectionDataUpdateable Action="Update" SectionTypeCode="NEW" SubSectionTypeCode="ONE">
        <Key>
          <SectionSequence>10</SectionSequence>
        </Key>
        <IsDeleted>true</IsDeleted>
      </SectionDataUpdateable>
      <SectionDataUpdateable Action="Nothing" SectionTypeCode="TEST" SubSectionTypeCode="ONE">
        <Key>
          <SectionSequence>99</SectionSequence>
        </Key>
        <IsDeleted>dontcare</IsDeleted>
      </SectionDataUpdateable>
      <SectionDataUpdateable Action="Update" SectionTypeCode="OLD" SubSectionTypeCode="TWO">
        <Key>
          <SectionSequence>05</SectionSequence>
        </Key>
        <IsDeleted>true</IsDeleted>
      </SectionDataUpdateable>
      <!--
            /*********************************************
            NEW SECTION TO BE INSERTED BEFORE THIS COMMENT
            *********************************************/
            -->
    </Sections>
    <BookDataExts>
      <MasterStatusCode>BOOKEXTN</MasterStatusCode>
      <EffectiveDate>2017-07-28</EffectiveDate>
    </BookDataExts>
  </BookMaster>
  <ReturnFields>false</ReturnFields>
</BookUpdateable>

You should put in some sanity checks such as testing that nameCodeSections IsNot Nothing before using nameCodeSections(0).

References:

'xsi' is an undeclared prefix using XmlDocument

Converting XElement into XmlNode

Appending an XMLChildnode from one XML to another XML file


问:
Using multiple vendor-specific CSS selectors at once
I'm styling placeholder text, and need to use several vendor-prefixed selectors so that it works in different browsers.  When I put each of them as a separate code block, it works.  However, if I use a comma-separated list of selectors instead of repeating the same CSS for each of them, it won't work.  Can anyone explain?

This works:

input[type=text]::-webkit-input-placeholder {
    color: green;
}
input[type=text]::-moz-placeholder {
    color: green;
}
input[type=text]:-ms-input-placeholder {
    color: green;
}
input[type=text]:-moz-placeholder {
   color: green;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><input type="text" placeholder="Placeholder Text" /></code>```

But this doesn't:

input[type=text]::-webkit-input-placeholder,
input[type=text]::-moz-placeholder,
input[type=text]:-ms-input-placeholder,
input[type=text]:-moz-placeholder {
     color: green;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><input type="text" placeholder="Placeholder Text" /></code>```

Why?

答:
Unfortunately, you can't.

When a selector that the browser does recognise as valid is found, it stops execution of the code block following it.

Only one of the vendor-prefixed selectors you are using will exist in each browsers (for example WebKit browsers do not have the Mozilla and Microsoft vendor-prefixed selectors); therefore you will never be able to execute that block as there is no browser where all three pseudo-selectors are valid.

However...

... you can simply use three different blocks. For example, this should work:

input[type=text]:focus::-webkit-input-placeholder {
  color: green;
}

input[type=text]:focus::-ms-input-placeholder {
  color: green;
}

input[type=text]:focus::-moz-placeholder {
    color: green;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><input type="text" placeholder="Hello, world!"></code>```

If you have a lot of code, you could use a preprocessor like LESS or SASS to dynamically put the same code inside each block.

Body:
I'm styling placeholder text, and need to use several vendor-prefixed selectors so that it works in different browsers.  When I put each of them as a separate code block, it works.  However, if I use a comma-separated list of selectors instead of repeating the same CSS for each of them, it won't work.  Can anyone explain?

This works:

input[type=text]::-webkit-input-placeholder {
    color: green;
}
input[type=text]::-moz-placeholder {
    color: green;
}
input[type=text]:-ms-input-placeholder {
    color: green;
}
input[type=text]:-moz-placeholder {
   color: green;
}

<input type="text" placeholder="Placeholder Text" />

But this doesn't:

input[type=text]::-webkit-input-placeholder,
input[type=text]::-moz-placeholder,
input[type=text]:-ms-input-placeholder,
input[type=text]:-moz-placeholder {
     color: green;
}

<input type="text" placeholder="Placeholder Text" />

Why?

Body:
Unfortunately, you can't.

When a selector that the browser does recognise as valid is found, it stops execution of the code block following it.

Only one of the vendor-prefixed selectors you are using will exist in each browsers (for example WebKit browsers do not have the Mozilla and Microsoft vendor-prefixed selectors); therefore you will never be able to execute that block as there is no browser where all three pseudo-selectors are valid.

However...

... you can simply use three different blocks. For example, this should work:

input[type=text]:focus::-webkit-input-placeholder {
  color: green;
}

input[type=text]:focus::-ms-input-placeholder {
  color: green;
}

input[type=text]:focus::-moz-placeholder {
    color: green;
}

<input type="text" placeholder="Hello, world!">

If you have a lot of code, you could use a preprocessor like LESS or SASS to dynamically put the same code inside each block.


问:
Can I review incoming changes in TortoiseSVN like in Eclipse before updating?
The synchronize view of Eclipse is very nice to see incoming changes from everybody before updating my codebase.

Is there a similar feature in TortoiseSVN? I can only compare 2 revisions there, I did not find any functionality to compare my working copy (which is a mix of modified files and files from various revisions) with the HEAD revision easily!

答:
Use the Check-For-Modifications dialog, then click on the "Check Repository" button.
That will show you which files are modified in the repository.</p>


问:
Angular2/Ionic2 circular dependent modules because of navigation between pages
I was refactoring my project to match the Angular2 styleguide at https://angular.io/guide/styleguide At first I had one module so there was no problem. Now while refactoring and with splitting into modules I got circular dependencies because of the navigation between pages of different modules.

Simplified, I have three modules, each having components:

Shared

BookListItemComponent

AjaxSpinnerComponent

FormHelperComponent

...

Books

BookComponent

Shops

ShopListComponent

Modules Books and Shops each import Shared. The BookListItemComponent shows a book title, and when tapped navigates to the BookComponent which show the book's details.

The ShopListComponent shows a list of books of a certain shop.

Since the Books module imports the Shared module to use the spinner etc. this creates a circular dependency. How are we supposed to solve this?

In an app you navigate between pages of different modules. I don't see a way to avoid having these pointing at each other. Especially with the BookListItemComponent which is used all over the app to list books.

I have also looked at:

https://forum.ionicframework.com/t/ionic2-navigation-circular-depencies/41123/6

Circular dependency injection angular 2

But couldn't really map this to my problem.

答:
So I feel your pain in refactoring all of your code. We went through the same thing with one of our apps at work and it was a pain. On the backside of it though, well worth it! The way ionic suggests you to organize your files is not sustainable. I have a couple thoughts and ideas for you based on going through the same thing that might help you out.

First off, putting everything back in the same module is not the best idea, because then you end back where you started with the disorganized code as ionic would have you do it, rather than the organized code as Angular suggests. In general, Angular suggests some great patterns, and I think it's worth the struggle to get your code in line with their suggestions.

Secondly, and this is the main point, are you using deep links in your app? If you are, there is a fantastic, barely documented feature you get with deeplinks to avoid circular dependency within pages. Suppose you have a page with the following deep link config:

```<code>{
  component: MyCoolPage, // the page component class
  name: 'MyCoolPage',    // I use the name of the class but can be any sting you want
  segment: 'cool-page'   // optional, not related to the problem,
                         // but it's probably best to use this field as well
}
</code>```

Whenever you want to navigate to MyCoolPage, instead of doing navCtrl.push(MyCoolPage), you can now do navCtrl.push('MyCoolPage') // or whatever string name you gave the page. So now you're navigating to pages via string names, which eliminates the need for importing pages whenever you want to navigate to it. This feature has existed since ionic 2, although I did not realize you could do this until updating to ionic 3.

Thirdly, more of a design consideration than anything else, you might want to reconsider navigating to pages from within components. Generally what we do is emit events up to the parent page components, and then have the page component handle pushing or popping the nav stack. Your BookListItemComponent shouldn't be causing you problems. If that is something in the shared module, used throughout the app, it shouldn't be depending on other modules. Your shared module shouldn't depend on anything else besides the ionic and angular modules you need to import.

Body:
So I feel your pain in refactoring all of your code. We went through the same thing with one of our apps at work and it was a pain. On the backside of it though, well worth it! The way ionic suggests you to organize your files is not sustainable. I have a couple thoughts and ideas for you based on going through the same thing that might help you out.

First off, putting everything back in the same module is not the best idea, because then you end back where you started with the disorganized code as ionic would have you do it, rather than the organized code as Angular suggests. In general, Angular suggests some great patterns, and I think it's worth the struggle to get your code in line with their suggestions.

Secondly, and this is the main point, are you using deep links in your app? If you are, there is a fantastic, barely documented feature you get with deeplinks to avoid circular dependency within pages. Suppose you have a page with the following deep link config:

{
  component: MyCoolPage, // the page component class
  name: 'MyCoolPage',    // I use the name of the class but can be any sting you want
  segment: 'cool-page'   // optional, not related to the problem,
                         // but it's probably best to use this field as well
}

Whenever you want to navigate to MyCoolPage, instead of doing navCtrl.push(MyCoolPage), you can now do navCtrl.push('MyCoolPage') // or whatever string name you gave the page. So now you're navigating to pages via string names, which eliminates the need for importing pages whenever you want to navigate to it. This feature has existed since ionic 2, although I did not realize you could do this until updating to ionic 3.

Thirdly, more of a design consideration than anything else, you might want to reconsider navigating to pages from within components. Generally what we do is emit events up to the parent page components, and then have the page component handle pushing or popping the nav stack. Your BookListItemComponent shouldn't be causing you problems. If that is something in the shared module, used throughout the app, it shouldn't be depending on other modules. Your shared module shouldn't depend on anything else besides the ionic and angular modules you need to import.


问:
How to specify python3 kernel in jupyter in pyCharm?
Here is my setting

and this is my script

I am trying to use jupyter notebook in pyCharm, but it kept using python2 instead of python3.

Any idea about this problem?

Add:

this pic is running jupyter notebook in chrome.

答:
The preferences image you show is indeed how you would setup your interpreter for PyCharm, but that's not what the output/logging of PyCharm looks like. I'm guessing that's a jupyter-notebook display, which means you are running into the issue in jupyter-notebook and not PyCharm. So you need to change your setup for jupyter. Based on some quick searching pip install jupyter will install a python 2.7 version of jupyter. Sounds like what you want is

pip3 install jupyter

which will install the python3 version for you. You will likely have to uninstall your current version of jupyter.


问:
Auto triggering of google PlaceAutocompleteFragment
```<code><fragment
     android:id="@+id/place_autocomplete_fragment"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:name="com.google.android.gms.location.places.ui.PlaceAutocompleteFragment"/>
</code>```

I am reading the fragment by

PlaceAutoCompleteFragment fromCity = (PlaceAutocompleteFragment)getFragmentManager().findFragmentById(R.id.source);

View destinationClearView = fromPlace.getView().findViewById(R.id.place_autocomplete_clear_button);

But destinationClearView.setVisibility(View.INVISIBLE) is not working, How to acheive that?

答:
It's not good way, but it's work.</p>

```<code>View close = viewOfFragment.findViewById(R.id.place_autocomplete_clear_button);
ViewsUtils.setVisible(false, close);
lp = (LinearLayout.LayoutParams) close.getLayoutParams();
lp.height = 1;
lp.width = 1;
close.requestLayout();
</code>```

Body:
<fragment
     android:id="@+id/place_autocomplete_fragment"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:name="com.google.android.gms.location.places.ui.PlaceAutocompleteFragment"/>

I am reading the fragment by

PlaceAutoCompleteFragment fromCity = (PlaceAutocompleteFragment)getFragmentManager().findFragmentById(R.id.source);

View destinationClearView = fromPlace.getView().findViewById(R.id.place_autocomplete_clear_button);

But destinationClearView.setVisibility(View.INVISIBLE) is not working, How to acheive that?

Body:
It's not good way, but it's work.

View close = viewOfFragment.findViewById(R.id.place_autocomplete_clear_button);
ViewsUtils.setVisible(false, close);
lp = (LinearLayout.LayoutParams) close.getLayoutParams();
lp.height = 1;
lp.width = 1;
close.requestLayout();


问:
Pandas - Replace values in a DataFrame Based on a Boollean DataFrame
I'm using Pandas v0.20.2 and I have DataFrame, like the following:

```<code>df = pd.DataFrame(dict(a=[0,1], b=[3,4], c=[6,7]),
              index=['spam', 'ham'])
#       a  b  c
# spam  0  3  6
# ham   1  4  7
</code>```

And I have another DataFrame that is a mask:

```<code>mask = pd.DataFrame(dict(a=[True,False], b=[True,True]),
                index=['spam', 'ham'])
#           a     b
# spam   True  True
# ham   False  True
</code>```

And I want to set the values in df equal to 999 where it is True in the mask.

I thought that the following would work:

```<code>df[mask] = 999
</code>```

But it doesn't. I get the error below:

```<code>ValueError                                Traceback (most recent call last)
<ipython-input-65-503f937859ab> in <module>()
----> 1 df[mask] = 999

/home/gbra/anaconda3/envs/outer_disk/lib/python2.7/site-packages/pandas/core/frame.pyc in __setitem__(self, key, value)
   2326             self._setitem_array(key, value)
   2327         elif isinstance(key, DataFrame):
-> 2328             self._setitem_frame(key, value)
   2329         else:
   2330             # set column

/home/gbra/anaconda3/envs/outer_disk/lib/python2.7/site-packages/pandas/core/frame.pyc in _setitem_frame(self, key, value)
   2364         self._check_inplace_setting(value)
   2365         self._check_setitem_copy()
-> 2366         self._where(-key, value, inplace=True)
   2367
   2368     def _ensure_valid_index(self, value):

/home/gbra/anaconda3/envs/outer_disk/lib/python2.7/site-packages/pandas/core/generic.pyc in _where(self, cond, other, inplace, axis, level, try_cast, raise_on_error)
   5096             for dt in cond.dtypes:
   5097                 if not is_bool_dtype(dt):
-> 5098                     raise ValueError(msg.format(dtype=dt))
   5099
   5100         cond = cond.astype(bool, copy=False)

ValueError: Boolean array expected for the condition, not float64
</code>```

I would appreciate any help on this.

答:
This will do the job:

```<code>df = pd.DataFrame(dict(a=[0,1], b=[3,4], c=[6,7]),
              index=['spam', 'ham'])
mask = pd.DataFrame(dict(a=[True,False], b=[True,True]),
                index=['spam', 'ham'])
df.iloc[mask] = 999
</code>```

Then df is

```<code>        a   b     c
spam    999 999   6
ham     1   999   7
</code>```

Body:
I'm using Pandas v0.20.2 and I have DataFrame, like the following:

df = pd.DataFrame(dict(a=[0,1], b=[3,4], c=[6,7]),
              index=['spam', 'ham'])
#       a  b  c
# spam  0  3  6
# ham   1  4  7

And I have another DataFrame that is a mask:

mask = pd.DataFrame(dict(a=[True,False], b=[True,True]),
                index=['spam', 'ham'])
#           a     b
# spam   True  True
# ham   False  True

And I want to set the values in df equal to 999 where it is True in the mask.

I thought that the following would work:

df[mask] = 999

But it doesn't. I get the error below:

ValueError                                Traceback (most recent call last)
<ipython-input-65-503f937859ab> in <module>()
----> 1 df[mask] = 999

/home/gbra/anaconda3/envs/outer_disk/lib/python2.7/site-packages/pandas/core/frame.pyc in __setitem__(self, key, value)
   2326             self._setitem_array(key, value)
   2327         elif isinstance(key, DataFrame):
-> 2328             self._setitem_frame(key, value)
   2329         else:
   2330             # set column

/home/gbra/anaconda3/envs/outer_disk/lib/python2.7/site-packages/pandas/core/frame.pyc in _setitem_frame(self, key, value)
   2364         self._check_inplace_setting(value)
   2365         self._check_setitem_copy()
-> 2366         self._where(-key, value, inplace=True)
   2367
   2368     def _ensure_valid_index(self, value):

/home/gbra/anaconda3/envs/outer_disk/lib/python2.7/site-packages/pandas/core/generic.pyc in _where(self, cond, other, inplace, axis, level, try_cast, raise_on_error)
   5096             for dt in cond.dtypes:
   5097                 if not is_bool_dtype(dt):
-> 5098                     raise ValueError(msg.format(dtype=dt))
   5099
   5100         cond = cond.astype(bool, copy=False)

ValueError: Boolean array expected for the condition, not float64

I would appreciate any help on this.

Body:
This will do the job:

df = pd.DataFrame(dict(a=[0,1], b=[3,4], c=[6,7]),
              index=['spam', 'ham'])
mask = pd.DataFrame(dict(a=[True,False], b=[True,True]),
                index=['spam', 'ham'])
df.iloc[mask] = 999

Then df is

        a   b     c
spam    999 999   6
ham     1   999   7